From 619acd84fbb91208302c508a14a5e546e127f02d Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 16:56:06 +0300 Subject: [PATCH 01/10] feat(vault): distribute the node corpus separately from the package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wheel shipped 302 nodes and 2.65 MB — roughly two thirds of the package — that no user could reach. ``resolve_global_vault`` picks an explicit argument, then AKMS_GLOBAL_VAULT, then ``global_vault`` from the propagation config, then ~/.claude/akms/nodes. The package directory is on none of those paths, and nothing copied the corpus out of it, so every ``pip install akms`` carried a corpus the runtime would never read. Verified directly against the published 0.3.0 wheel before removing anything. Removing it drops the wheel from 1.3 MB to 320 KB. Every functional bundled asset still ships: skills, qmd wrappers, hooks, agents, commands, the kernel. ``package-data`` is now enumerated rather than ``_bundled/**/*``. The blanket glob is how the corpus came to ship in the first place, and how ``.DS_Store`` reached users; an enumerated list means a corpus dropped back into _bundled cannot silently re-enter the wheel. **akms vault status / install.** Removing the corpus exposes a gap that was always there: installation.md tells a new user to ``mkdir -p ~/.claude/akms/nodes`` and no documentation says where nodes come from. Every fresh install has had an empty vault. ``vault install`` takes a directory, a .tar.gz, or an https URL. Nothing in AKMS writes to the global vault on its own, and that stays true: this is a foreground command that reports what it will do and refuses to replace a populated vault without --force. It also refuses a source with no nodes, a source whose markdown declares no ``akms_schema``, plain http, and any archive member that resolves outside the destination. Content is staged beside the vault and swapped in, so an interrupted install cannot leave a half-written vault where a working one used to be. **Test fixture.** The seed integration tests used the shipped corpus as their fixture. They now run against a pinned 52-node subset under tests/fixtures/ — the six skill-* nodes they assert over, the closure of every node their edges target, and every content_ref payload involved. Self-consistent, no dangling edges, 300 KB, and not packaged. All 27 of those tests pass unchanged. Corpus-wide QA belongs with the vault. One real bug surfaced while testing the tarball path: macOS ``tar`` writes AppleDouble ``._name`` companions beside every file, they extract as files ending in .md, and they were both counted as nodes and installed into the vault, where the compiler would try to parse resource-fork data as v2 nodes. Filtered on copy, with a regression test. Verified: 767 tests pass, ruff format and check clean, no new pyright errors, and an installed vault compiles to a 52-node, 165-edge graph end to end. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- packages/akms/pyproject.toml | 13 +- .../global_nodes/composite-delamination.md | 170 ------ .../composite-failure-criteria.md | 136 ----- .../global_nodes/composite-homogenization.md | 145 ----- .../global_nodes/composite-laminate-theory.md | 137 ----- .../composite-progressive-damage.md | 141 ----- .../global_nodes/constit-elastic-predictor.md | 115 ---- .../constit-stress-update-architecture.md | 116 ---- .../constit-thermodynamic-framework.md | 110 ---- .../global_nodes/damage-bai-wierzbicki.md | 107 ---- .../global_nodes/damage-cockcroft-latham.md | 109 ---- .../damage-continuum-framework.md | 113 ---- .../global_nodes/damage-element-erosion.md | 116 ---- .../damage-gtn-consistent-tangent.md | 106 ---- .../global_nodes/damage-gtn-return-mapping.md | 116 ---- .../damage-gtn-shear-extension.md | 106 ---- .../global_nodes/damage-gtn-void-evolution.md | 108 ---- .../global_nodes/damage-gtn-yield-function.md | 108 ---- .../damage-johnson-cook-failure.md | 109 ---- .../global_nodes/damage-nonlocal-gradient.md | 111 ---- .../global_nodes/damage-nonlocal-integral.md | 107 ---- .../_bundled/global_nodes/damage-spall.md | 108 ---- .../global_nodes/elastic-anisotropic.md | 126 ---- .../global_nodes/elastic-eos-coupling.md | 139 ----- .../global_nodes/eos-mie-gruneisen.md | 104 ---- .../_bundled/global_nodes/eos-overview.md | 108 ---- .../_bundled/global_nodes/eos-polynomial.md | 106 ---- .../global_nodes/fem-assembly-algorithm.md | 108 ---- .../global_nodes/fem-hourglass-control.md | 105 ---- .../global_nodes/fem-isoparametric-mapping.md | 244 -------- .../global_nodes/fem-locking-remedies.md | 99 ---- .../global_nodes/fem-mixed-methods.md | 92 --- .../global_nodes/fem-newton-raphson.md | 104 ---- .../global_nodes/fem-shape-functions.md | 100 ---- .../_bundled/global_nodes/fem-tl-b-matrix.md | 239 -------- .../global_nodes/fem-tl-linearization.md | 244 -------- .../global_nodes/fem-tl-matrix-free-action.md | 96 --- .../_bundled/global_nodes/fem-tl-weak-form.md | 251 -------- .../global_nodes/fem-weak-form-derivation.md | 101 ---- .../global_nodes/fft-composite-voxels.md | 125 ---- .../global_nodes/fft-convergence-schemes.md | 173 ------ .../global_nodes/fft-coupled-problems.md | 203 ------- .../fft-discretization-fd-highorder.md | 134 ----- .../global_nodes/fft-discretization-fem.md | 142 ----- .../fft-discretization-moulinec-suquet.md | 188 ------ .../fft-discretization-staggered.md | 158 ----- .../global_nodes/fft-discretization-willot.md | 203 ------- .../_bundled/global_nodes/fft-dual-scheme.md | 178 ------ .../global_nodes/fft-finite-strain.md | 183 ------ .../_bundled/global_nodes/fft-freq-grid.md | 168 ------ .../global_nodes/fft-galerkin-basics.md | 178 ------ .../global_nodes/fft-green-operator.md | 123 ---- .../global_nodes/fft-lippmann-schwinger.md | 140 ----- .../_bundled/global_nodes/fft-mixed-bc.md | 138 ----- .../_bundled/global_nodes/fft-periodic-bc.md | 140 ----- .../_bundled/global_nodes/fft-phase-field.md | 166 ------ .../_bundled/global_nodes/fft-polycrystal.md | 233 -------- .../global_nodes/fft-reference-medium.md | 155 ----- .../fft-solver-barzilai-borwein.md | 150 ----- .../global_nodes/fft-solver-basic-scheme.md | 184 ------ .../global_nodes/fft-solver-eyre-milton.md | 171 ------ .../global_nodes/fft-solver-fast-gradient.md | 175 ------ .../global_nodes/fft-solver-krylov-cg.md | 214 ------- .../global_nodes/fft-solver-krylov-minres.md | 174 ------ .../global_nodes/fft-solver-newton-krylov.md | 173 ------ .../global_nodes/fft-solver-nonlinear-cg.md | 188 ------ .../fft-solver-polarization-admm.md | 173 ------ .../global_nodes/fft-solver-quasi-newton.md | 186 ------ .../_bundled/global_nodes/gmsh-extrusion.md | 104 ---- .../global_nodes/gmsh-geometry-api.md | 108 ---- .../global_nodes/gmsh-mesh-formats.md | 92 --- .../global_nodes/gmsh-mesh-quality.md | 101 ---- .../global_nodes/gmsh-mesh-size-control.md | 101 ---- .../global_nodes/gmsh-meshing-algorithms.md | 109 ---- .../_bundled/global_nodes/gmsh-periodicity.md | 94 --- .../global_nodes/gmsh-physical-groups.md | 91 --- .../_bundled/global_nodes/gmsh-python-api.md | 88 --- .../global_nodes/gmsh-structured-meshing.md | 103 ---- .../homogenization-cell-problem.md | 135 ----- .../kinematics-convected-coordinates.md | 104 ---- .../kinematics-corotational-update.md | 104 ---- .../global_nodes/kinematics-lie-derivative.md | 229 -------- .../kinematics-logarithmic-strain.md | 248 -------- .../kinematics-motion-deformation-gradient.md | 233 -------- .../kinematics-multiplicative-decomp.md | 246 -------- .../kinematics-objective-rates.md | 109 ---- .../kinematics-polar-decomposition.md | 112 ---- .../global_nodes/kinematics-strain-tensors.md | 109 ---- .../kinematics-velocity-gradient.md | 224 ------- .../global_nodes/knowledge/graph/graph.json | 14 - .../moose-action-auto-creation.md | 119 ---- .../global_nodes/moose-action-system.md | 274 --------- .../moose-allen-cahn-cahn-hilliard.md | 233 -------- .../global_nodes/moose-allen-cahn-kernels.md | 135 ----- .../global_nodes/moose-assembly-loop.md | 148 ----- .../moose-cahn-hilliard-kernels.md | 109 ---- .../akms/_bundled/global_nodes/moose-cdm.md | 301 ---------- .../global_nodes/moose-continuum-damage.md | 308 ---------- .../global_nodes/moose-cp-hardening.md | 150 ----- .../global_nodes/moose-cp-orientation.md | 194 ------ .../global_nodes/moose-cp-polycrystal.md | 129 ---- .../global_nodes/moose-cp-stress-update.md | 105 ---- .../global_nodes/moose-cp-twinning.md | 126 ---- .../global_nodes/moose-creep-models.md | 196 ------- .../moose-creep-viscoplasticity.md | 285 --------- .../moose-crystal-plasticity-advanced.md | 247 -------- .../global_nodes/moose-crystal-plasticity.md | 411 ------------- .../moose-derivative-parsed-material.md | 407 ------------- .../global_nodes/moose-eigenstrains.md | 170 ------ .../global_nodes/moose-elasticity-tensor.md | 211 ------- .../moose-factory-registration.md | 149 ----- .../global_nodes/moose-input-file-anatomy.md | 166 ------ .../global_nodes/moose-jfnk-architecture.md | 125 ---- .../moose-jfnk-preconditioning.md | 234 -------- .../global_nodes/moose-mesh-adaptivity.md | 214 ------- .../_bundled/global_nodes/moose-mesh-amr.md | 204 ------- .../moose-multi-phase-component.md | 146 ----- .../global_nodes/moose-multiapp-coupling.md | 127 ---- .../global_nodes/moose-multiapp-transfers.md | 141 ----- .../moose-nucleation-grain-growth.md | 374 ------------ .../global_nodes/moose-object-factory.md | 390 ------------- .../moose-objective-stress-rates.md | 169 ------ .../moose-objectivity-frame-operations.md | 552 ------------------ .../moose-output-postprocessing.md | 113 ---- .../global_nodes/moose-output-system.md | 103 ---- .../global_nodes/moose-petsc-fieldsplit.md | 123 ---- .../_bundled/global_nodes/moose-petsc-gpu.md | 111 ---- .../global_nodes/moose-petsc-interface.md | 466 --------------- .../global_nodes/moose-petsc-linalg.md | 154 ----- .../global_nodes/moose-petsc-matshell.md | 149 ----- .../moose-pf-constitutive-params.md | 119 ---- .../global_nodes/moose-pf-constraints.md | 95 --- .../global_nodes/moose-pf-elastic-coupling.md | 239 -------- .../global_nodes/moose-pf-energy-coded.md | 273 --------- .../global_nodes/moose-pf-energy-parsing.md | 153 ----- .../global_nodes/moose-pf-grain-growth.md | 184 ------ .../global_nodes/moose-pf-multi-component.md | 28 - .../global_nodes/moose-pf-multi-phase.md | 127 ---- .../global_nodes/moose-pf-nucleation.md | 197 ------- .../global_nodes/moose-pf-solver-strategy.md | 216 ------- .../moose-phase-field-mechanics-coupling.md | 349 ----------- .../moose-phase-field-numerics.md | 300 ---------- .../global_nodes/moose-preconditioning.md | 130 ----- .../moose-push-pull-operations.md | 214 ------- .../moose-return-mapping-algorithm.md | 136 ----- .../global_nodes/moose-return-mapping-base.md | 311 ---------- .../moose-return-mapping-extension.md | 192 ------ .../global_nodes/moose-strain-classes.md | 169 ------ .../global_nodes/moose-strain-formulations.md | 318 ---------- .../moose-stress-computation-chain.md | 296 ---------- .../moose-stress-dispatch-chain.md | 115 ---- .../global_nodes/moose-stress-measures.md | 130 ----- .../global_nodes/moose-system-taxonomy.md | 256 -------- .../global_nodes/moose-threaded-assembly.md | 134 ----- .../global_nodes/moose-total-lagrangian.md | 108 ---- .../moose-viscoplastic-flow-rules.md | 109 ---- .../global_nodes/moose-wbm-calphad.md | 114 ---- .../global_nodes/moose-wbm-formulation.md | 126 ---- .../global_nodes/moose-wbm-implementation.md | 247 -------- .../global_nodes/moose-wbm-kks-model.md | 458 --------------- .../_bundled/global_nodes/optim-as-solver.md | 277 --------- .../global_nodes/optim-constrained.md | 146 ----- .../_bundled/global_nodes/optim-lbfgs-fem.md | 126 ---- .../akms/_bundled/global_nodes/optim-lbfgs.md | 135 ----- .../global_nodes/optim-line-search.md | 138 ----- .../global_nodes/optim-newton-krylov.md | 104 ---- .../global_nodes/optim-nonlinear-cg.md | 119 ---- .../global_nodes/optim-trust-region.md | 96 --- .../optim-unconstrained-basics.md | 105 ---- .../global_nodes/pf-abaqus-umat-uel.md | 155 ----- .../global_nodes/pf-at1-regularization.md | 110 ---- .../global_nodes/pf-at2-regularization.md | 194 ------ .../_bundled/global_nodes/pf-benchmarks.md | 123 ---- .../_bundled/global_nodes/pf-cohesive-zone.md | 115 ---- .../global_nodes/pf-ductile-mixed-mode.md | 128 ---- .../pf-ductile-plasticity-coupling.md | 116 ---- .../global_nodes/pf-dynamic-brittle.md | 107 ---- .../global_nodes/pf-dynamic-shear-bands.md | 107 ---- .../pf-energy-split-comparison.md | 109 ---- .../pf-explicit-time-integration.md | 122 ---- .../global_nodes/pf-fem-implementation.md | 106 ---- .../global_nodes/pf-monolithic-bfgs.md | 109 ---- .../global_nodes/pf-monolithic-scheme.md | 105 ---- .../global_nodes/pf-porous-ductile.md | 109 ---- .../global_nodes/pf-regularization-length.md | 107 ---- .../_bundled/global_nodes/pf-spallation.md | 106 ---- .../global_nodes/pf-spectral-split.md | 106 ---- .../global_nodes/pf-staggered-scheme.md | 110 ---- .../global_nodes/pf-thermomechanical.md | 106 ---- .../global_nodes/pf-variational-griffith.md | 193 ------ .../_bundled/global_nodes/pf-voldev-split.md | 93 --- .../plasticity-consistent-tangent-general.md | 106 ---- .../plasticity-consistent-tangent-j2.md | 106 ---- .../plasticity-cpp-nonassociative.md | 115 ---- .../global_nodes/plasticity-cutting-plane.md | 109 ---- .../global_nodes/plasticity-drucker-prager.md | 113 ---- .../global_nodes/plasticity-duvaut-lions.md | 164 ------ .../plasticity-exponential-map.md | 107 ---- .../plasticity-general-return-mapping.md | 111 ---- .../global_nodes/plasticity-hill48.md | 102 ---- .../plasticity-isotropic-hardening.md | 113 ---- .../global_nodes/plasticity-johnson-cook.md | 110 ---- .../plasticity-kinematic-hardening.md | 106 ---- .../plasticity-lode-triaxiality.md | 109 ---- .../plasticity-peirce-rate-tangent.md | 214 ------- .../global_nodes/plasticity-perzyna.md | 104 ---- .../global_nodes/plasticity-radial-return.md | 110 ---- .../global_nodes/plasticity-von-mises.md | 265 --------- .../plasticity-zerilli-armstrong.md | 96 --- .../_bundled/global_nodes/precond-amg-gpu.md | 111 ---- .../global_nodes/precond-amg-theory.md | 120 ---- .../global_nodes/precond-domain-decomp.md | 118 ---- .../global_nodes/precond-field-split-block.md | 117 ---- .../global_nodes/precond-geometric-mg.md | 98 ---- .../global_nodes/precond-gpu-alternatives.md | 117 ---- .../global_nodes/precond-ichol-ilu.md | 111 ---- .../precond-jacobi-block-jacobi.md | 105 ---- .../global_nodes/solver-bicgstab-algorithm.md | 101 ---- .../global_nodes/solver-cg-algorithm.md | 95 --- .../solver-convergence-diagnostics.md | 122 ---- .../_bundled/global_nodes/solver-direct.md | 103 ---- .../global_nodes/solver-explicit-dynamics.md | 97 --- .../global_nodes/solver-gmres-algorithm.md | 119 ---- .../global_nodes/solver-gpu-data-layout.md | 115 ---- .../global_nodes/solver-imex-splitting.md | 105 ---- .../akms/_bundled/global_nodes/solver-jfnk.md | 118 ---- .../global_nodes/solver-matrix-free-gpu.md | 89 --- .../solver-matrix-free-operator.md | 93 --- .../_bundled/global_nodes/solver-minres.md | 96 --- .../global_nodes/solver-newmark-hht.md | 102 ---- .../global_nodes/solver-pcg-algorithm.md | 99 ---- .../global_nodes/stress-cauchy-kirchhoff.md | 233 -------- .../global_nodes/stress-piola-kirchhoff.md | 236 -------- .../stress-push-forward-pull-back.md | 227 ------- .../stress-tangent-push-forward.md | 113 ---- .../tensor-christoffel-symbols.md | 93 --- .../tensor-covariant-derivative.md | 106 ---- .../global_nodes/tensor-curvilinear-bases.md | 101 ---- .../tensor-derivatives-scalars.md | 98 ---- .../tensor-derivatives-tensors.md | 106 ---- .../global_nodes/tensor-index-notation.md | 99 ---- .../global_nodes/tensor-invariants.md | 102 ---- .../tensor-isotropic-functions.md | 103 ---- .../global_nodes/tensor-mandel-notation.md | 94 --- .../_bundled/global_nodes/tensor-metric.md | 102 ---- .../global_nodes/tensor-operations.md | 258 -------- .../tensor-products-contractions.md | 102 ---- .../tensor-spectral-decomposition.md | 116 ---- .../global_nodes/tensor-voigt-notation.md | 93 --- .../global_nodes/thermal-adiabatic-shear.md | 105 ---- .../global_nodes/thermal-coupled-mechanics.md | 105 ---- .../global_nodes/thermal-softening.md | 100 ---- packages/akms/src/akms/cli/commands.py | 5 + packages/akms/src/akms/cli/vault_commands.py | 311 ++++++++++ .../akms/tests/akms/test_seed_integration.py | 24 +- .../akms/tests/akms/test_vault_commands.py | 179 ++++++ .../fixtures/vault}/cm-anisotropic-yield.md | 0 .../fixtures/vault}/cm-fft-galerkin.md | 0 .../vault}/cm-gtn-ductile-fracture.md | 0 .../fixtures/vault}/cm-kinematics-tl.md | 0 .../fixtures/vault}/cm-notation-cheatsheet.md | 0 .../fixtures/vault}/cm-objective-rates.md | 0 .../vault}/cm-phase-field-fracture.md | 0 .../fixtures/vault}/cm-solver-matrixfree.md | 0 .../fixtures/vault}/cm-tensor-calculus.md | 0 .../fixtures/vault}/cm-verification.md | 0 .../fixtures/vault}/cm-viscoplastic-thermo.md | 0 .../content/computational-mechanics/SKILL.md | 0 .../constitutive-anisotropic-yield.md | 0 .../constitutive-viscoplastic-thermo.md | 0 .../ductile-fracture-gtn-phasefield.md | 0 .../reference/fft-galerkin-micromechanics.md | 0 .../reference/kinematics-tl-convected.md | 0 .../reference/notation-cheatsheet.md | 0 .../reference/objective-rates-integration.md | 0 .../reference/phase-field-fracture.md | 0 .../solver-architecture-matrixfree.md | 0 .../reference/tensor-calculus.md | 0 .../reference/verification-benchmarks.md | 0 .../fixtures/vault}/content/gen-test/SKILL.md | 0 .../vault}/content/repo-documentor/SKILL.md | 0 .../assets/templates/TEMPLATES.md | 0 .../assets/templates/mkdocs.yml | 0 .../repo-documentor/references/CONTRACTS.md | 0 .../repo-documentor/references/CONVENTIONS.md | 0 .../repo-documentor/references/DIAGRAMS.md | 0 .../repo-documentor/references/PROFILES.md | 0 .../references/QUALITY_GATES.md | 0 .../references/SECURITY_HARDWARE.md | 0 .../repo-documentor/references/TEMPLATES.tex | 0 .../repo-documentor/references/VALIDATION.md | 0 .../repo-documentor/references/WORKFLOW.md | 0 .../vault}/content/shared/CONVENTIONS.md | 0 .../vault}/content/taichi-gpu-sim/SKILL.md | 0 .../content/taichi-gpu-sim/domains/fd.md | 0 .../content/taichi-gpu-sim/domains/fem.md | 0 .../content/taichi-gpu-sim/domains/fft.md | 0 .../taichi-gpu-sim/domains/linear-solvers.md | 0 .../content/taichi-gpu-sim/domains/mpm.md | 0 .../domains/time-integration.md | 0 .../references/continuum-tensors.md | 0 .../references/conventions-quickref.md | 0 .../references/data-layout-and-snode.md | 0 .../taichi-gpu-sim/references/gotchas.md | 0 .../taichi-gpu-sim/references/interop.md | 0 .../references/kernel-patterns.md | 0 .../references/numerical-safeguards.md | 0 .../taichi-gpu-sim/references/performance.md | 0 .../references/stress-integration.md | 0 .../references/style-and-architecture.md | 0 .../references/testing-and-validation.md | 0 .../content/taichi-sim-reviewer/SKILL.md | 0 .../examples/bad-kernel-review.md | 0 .../examples/pr-review-template.md | 0 .../references/ci-cd-guidance.md | 0 .../references/documentation-standards.md | 0 .../references/interface-compatibility.md | 0 .../references/review-checklist.md | 0 .../references/testing-verification.md | 0 .../fixtures/vault}/rd-asset-latex.md | 0 .../fixtures/vault}/rd-asset-mkdocs.md | 0 .../fixtures/vault}/rd-asset-templates-md.md | 0 .../fixtures/vault}/rd-ref-contracts.md | 0 .../fixtures/vault}/rd-ref-conventions.md | 0 .../fixtures/vault}/rd-ref-diagrams.md | 0 .../fixtures/vault}/rd-ref-profiles.md | 0 .../fixtures/vault}/rd-ref-quality-gates.md | 0 .../vault}/rd-ref-security-hardware.md | 0 .../fixtures/vault}/rd-ref-validation.md | 0 .../fixtures/vault}/rd-ref-workflow.md | 0 .../vault}/skill-computational-mechanics.md | 0 .../fixtures/vault}/skill-gen-test.md | 0 .../fixtures/vault}/skill-repo-documentor.md | 0 .../vault}/skill-shared-conventions.md | 0 .../fixtures/vault}/skill-taichi-gpu-sim.md | 0 .../vault}/skill-taichi-sim-reviewer.md | 0 .../fixtures/vault}/tgs-dom-fd.md | 0 .../fixtures/vault}/tgs-dom-fem.md | 0 .../fixtures/vault}/tgs-dom-fft.md | 0 .../fixtures/vault}/tgs-dom-linear-solvers.md | 0 .../fixtures/vault}/tgs-dom-mpm.md | 0 .../vault}/tgs-dom-time-integration.md | 0 .../vault}/tgs-ref-continuum-tensors.md | 0 .../vault}/tgs-ref-conventions-quickref.md | 0 .../fixtures/vault}/tgs-ref-data-layout.md | 0 .../fixtures/vault}/tgs-ref-gotchas.md | 0 .../fixtures/vault}/tgs-ref-interop.md | 0 .../vault}/tgs-ref-kernel-patterns.md | 0 .../vault}/tgs-ref-numerical-safeguards.md | 0 .../fixtures/vault}/tgs-ref-performance.md | 0 .../vault}/tgs-ref-stress-integration.md | 0 .../vault}/tgs-ref-style-architecture.md | 0 .../vault}/tgs-ref-testing-validation.md | 0 .../vault}/tsr-ex-bad-kernel-review.md | 0 .../fixtures/vault}/tsr-ex-pr-template.md | 0 .../fixtures/vault}/tsr-ref-ci-cd.md | 0 .../vault}/tsr-ref-documentation-standards.md | 0 .../vault}/tsr-ref-interface-compatibility.md | 0 .../vault}/tsr-ref-review-checklist.md | 0 .../vault}/tsr-ref-testing-verification.md | 0 360 files changed, 526 insertions(+), 38136 deletions(-) delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/composite-delamination.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/composite-failure-criteria.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/composite-homogenization.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/composite-laminate-theory.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/composite-progressive-damage.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/constit-elastic-predictor.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/constit-stress-update-architecture.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/constit-thermodynamic-framework.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-bai-wierzbicki.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-cockcroft-latham.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-continuum-framework.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-element-erosion.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-gtn-consistent-tangent.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-gtn-return-mapping.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-gtn-shear-extension.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-gtn-void-evolution.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-gtn-yield-function.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-johnson-cook-failure.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-nonlocal-gradient.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-nonlocal-integral.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/damage-spall.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/elastic-anisotropic.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/elastic-eos-coupling.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/eos-mie-gruneisen.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/eos-overview.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/eos-polynomial.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-assembly-algorithm.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-hourglass-control.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-isoparametric-mapping.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-locking-remedies.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-mixed-methods.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-newton-raphson.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-shape-functions.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-tl-b-matrix.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-tl-linearization.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-tl-matrix-free-action.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-tl-weak-form.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fem-weak-form-derivation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-composite-voxels.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-convergence-schemes.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-coupled-problems.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-discretization-fd-highorder.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-discretization-fem.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-discretization-moulinec-suquet.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-discretization-staggered.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-discretization-willot.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-dual-scheme.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-finite-strain.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-freq-grid.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-galerkin-basics.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-green-operator.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-lippmann-schwinger.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-mixed-bc.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-periodic-bc.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-phase-field.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-polycrystal.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-reference-medium.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-barzilai-borwein.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-basic-scheme.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-eyre-milton.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-fast-gradient.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-krylov-cg.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-krylov-minres.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-newton-krylov.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-nonlinear-cg.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-polarization-admm.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/fft-solver-quasi-newton.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-extrusion.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-geometry-api.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-formats.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-quality.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-size-control.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-meshing-algorithms.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-periodicity.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-physical-groups.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-python-api.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/gmsh-structured-meshing.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/homogenization-cell-problem.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-convected-coordinates.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-corotational-update.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-lie-derivative.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-logarithmic-strain.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-motion-deformation-gradient.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-multiplicative-decomp.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-objective-rates.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-polar-decomposition.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-strain-tensors.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/kinematics-velocity-gradient.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/knowledge/graph/graph.json delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-action-auto-creation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-action-system.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-allen-cahn-cahn-hilliard.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-allen-cahn-kernels.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-assembly-loop.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-cahn-hilliard-kernels.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-cdm.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-continuum-damage.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-cp-hardening.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-cp-orientation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-cp-polycrystal.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-cp-stress-update.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-cp-twinning.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-creep-models.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-creep-viscoplasticity.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-crystal-plasticity-advanced.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-crystal-plasticity.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-derivative-parsed-material.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-eigenstrains.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-elasticity-tensor.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-factory-registration.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-input-file-anatomy.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-jfnk-architecture.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-jfnk-preconditioning.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-mesh-adaptivity.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-mesh-amr.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-multi-phase-component.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-multiapp-coupling.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-multiapp-transfers.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-nucleation-grain-growth.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-object-factory.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-objective-stress-rates.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-objectivity-frame-operations.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-output-postprocessing.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-output-system.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-petsc-fieldsplit.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-petsc-gpu.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-petsc-interface.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-petsc-linalg.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-petsc-matshell.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-constitutive-params.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-constraints.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-elastic-coupling.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-energy-coded.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-energy-parsing.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-grain-growth.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-multi-component.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-multi-phase.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-nucleation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-pf-solver-strategy.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-phase-field-mechanics-coupling.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-phase-field-numerics.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-preconditioning.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-push-pull-operations.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-algorithm.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-base.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-extension.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-strain-classes.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-strain-formulations.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-stress-computation-chain.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-stress-dispatch-chain.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-stress-measures.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-system-taxonomy.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-threaded-assembly.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-total-lagrangian.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-viscoplastic-flow-rules.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-wbm-calphad.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-wbm-formulation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-wbm-implementation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/moose-wbm-kks-model.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/optim-as-solver.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/optim-constrained.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/optim-lbfgs-fem.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/optim-lbfgs.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/optim-line-search.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/optim-newton-krylov.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/optim-nonlinear-cg.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/optim-trust-region.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/optim-unconstrained-basics.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-abaqus-umat-uel.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-at1-regularization.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-at2-regularization.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-benchmarks.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-cohesive-zone.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-ductile-mixed-mode.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-ductile-plasticity-coupling.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-dynamic-brittle.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-dynamic-shear-bands.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-energy-split-comparison.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-explicit-time-integration.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-fem-implementation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-monolithic-bfgs.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-monolithic-scheme.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-porous-ductile.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-regularization-length.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-spallation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-spectral-split.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-staggered-scheme.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-thermomechanical.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-variational-griffith.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/pf-voldev-split.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-consistent-tangent-general.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-consistent-tangent-j2.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-cpp-nonassociative.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-cutting-plane.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-drucker-prager.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-duvaut-lions.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-exponential-map.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-general-return-mapping.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-hill48.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-isotropic-hardening.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-johnson-cook.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-kinematic-hardening.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-lode-triaxiality.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-peirce-rate-tangent.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-perzyna.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-radial-return.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-von-mises.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/plasticity-zerilli-armstrong.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/precond-amg-gpu.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/precond-amg-theory.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/precond-domain-decomp.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/precond-field-split-block.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/precond-geometric-mg.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/precond-gpu-alternatives.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/precond-ichol-ilu.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/precond-jacobi-block-jacobi.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-bicgstab-algorithm.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-cg-algorithm.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-convergence-diagnostics.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-direct.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-explicit-dynamics.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-gmres-algorithm.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-gpu-data-layout.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-imex-splitting.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-jfnk.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-matrix-free-gpu.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-matrix-free-operator.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-minres.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-newmark-hht.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/solver-pcg-algorithm.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/stress-cauchy-kirchhoff.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/stress-piola-kirchhoff.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/stress-push-forward-pull-back.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/stress-tangent-push-forward.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-christoffel-symbols.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-covariant-derivative.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-curvilinear-bases.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-derivatives-scalars.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-derivatives-tensors.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-index-notation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-invariants.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-isotropic-functions.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-mandel-notation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-metric.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-operations.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-products-contractions.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-spectral-decomposition.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/tensor-voigt-notation.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/thermal-adiabatic-shear.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/thermal-coupled-mechanics.md delete mode 100644 packages/akms/src/akms/_bundled/global_nodes/thermal-softening.md create mode 100644 packages/akms/src/akms/cli/vault_commands.py create mode 100644 packages/akms/tests/akms/test_vault_commands.py rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-anisotropic-yield.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-fft-galerkin.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-gtn-ductile-fracture.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-kinematics-tl.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-notation-cheatsheet.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-objective-rates.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-phase-field-fracture.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-solver-matrixfree.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-tensor-calculus.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-verification.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/cm-viscoplastic-thermo.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/SKILL.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/constitutive-anisotropic-yield.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/constitutive-viscoplastic-thermo.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/ductile-fracture-gtn-phasefield.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/fft-galerkin-micromechanics.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/kinematics-tl-convected.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/notation-cheatsheet.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/objective-rates-integration.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/phase-field-fracture.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/solver-architecture-matrixfree.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/tensor-calculus.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/computational-mechanics/reference/verification-benchmarks.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/gen-test/SKILL.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/SKILL.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/assets/templates/TEMPLATES.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/assets/templates/mkdocs.yml (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/references/CONTRACTS.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/references/CONVENTIONS.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/references/DIAGRAMS.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/references/PROFILES.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/references/QUALITY_GATES.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/references/SECURITY_HARDWARE.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/references/TEMPLATES.tex (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/references/VALIDATION.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/repo-documentor/references/WORKFLOW.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/shared/CONVENTIONS.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/SKILL.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/domains/fd.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/domains/fem.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/domains/fft.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/domains/linear-solvers.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/domains/mpm.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/domains/time-integration.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/continuum-tensors.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/conventions-quickref.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/data-layout-and-snode.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/gotchas.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/interop.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/kernel-patterns.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/numerical-safeguards.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/performance.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/stress-integration.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/style-and-architecture.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-gpu-sim/references/testing-and-validation.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-sim-reviewer/SKILL.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-sim-reviewer/examples/bad-kernel-review.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-sim-reviewer/examples/pr-review-template.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-sim-reviewer/references/ci-cd-guidance.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-sim-reviewer/references/documentation-standards.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-sim-reviewer/references/interface-compatibility.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-sim-reviewer/references/review-checklist.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/content/taichi-sim-reviewer/references/testing-verification.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-asset-latex.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-asset-mkdocs.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-asset-templates-md.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-ref-contracts.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-ref-conventions.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-ref-diagrams.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-ref-profiles.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-ref-quality-gates.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-ref-security-hardware.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-ref-validation.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/rd-ref-workflow.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/skill-computational-mechanics.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/skill-gen-test.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/skill-repo-documentor.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/skill-shared-conventions.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/skill-taichi-gpu-sim.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/skill-taichi-sim-reviewer.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-dom-fd.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-dom-fem.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-dom-fft.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-dom-linear-solvers.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-dom-mpm.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-dom-time-integration.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-continuum-tensors.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-conventions-quickref.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-data-layout.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-gotchas.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-interop.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-kernel-patterns.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-numerical-safeguards.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-performance.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-stress-integration.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-style-architecture.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tgs-ref-testing-validation.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tsr-ex-bad-kernel-review.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tsr-ex-pr-template.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tsr-ref-ci-cd.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tsr-ref-documentation-standards.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tsr-ref-interface-compatibility.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tsr-ref-review-checklist.md (100%) rename packages/akms/{src/akms/_bundled/global_nodes => tests/fixtures/vault}/tsr-ref-testing-verification.md (100%) diff --git a/packages/akms/pyproject.toml b/packages/akms/pyproject.toml index b06b387..d0b53c5 100644 --- a/packages/akms/pyproject.toml +++ b/packages/akms/pyproject.toml @@ -81,8 +81,19 @@ where = ["src"] # from a built wheel and the qmd-backed search tools are inert in a # wheel-only install. [tool.setuptools.package-data] +# Enumerated rather than `_bundled/**/*`, so a node corpus dropped back into +# _bundled cannot silently re-enter the wheel. The previous blanket glob is how +# 302 nodes and 2.65 MB — roughly two thirds of the package — came to ship to +# every user despite `resolve_global_vault` never resolving to the package +# directory, so nothing could read them. Vaults are distributed separately; +# see `akms vault install`. akms = [ - "_bundled/**/*", + "_bundled/agents/**/*", + "_bundled/commands/**/*", + "_bundled/hooks/**/*", + "_bundled/qmd/**/*", + "_bundled/skills/**/*", + "_bundled/claude_md_kernel.md", ] [tool.pytest.ini_options] diff --git a/packages/akms/src/akms/_bundled/global_nodes/composite-delamination.md b/packages/akms/src/akms/_bundled/global_nodes/composite-delamination.md deleted file mode 100644 index 039cb85..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/composite-delamination.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -id: composite-delamination -title: Delamination & Cohesive Zone Models (CZM) -domain: computational-mechanics -subdomain: composites -tags: -- composites -- delamination -- CZM -- cohesive-zone -- BK-criterion -- interface-elements -status: established -confidence: 0.9 -source: hybrid -edges: -- to: composite-laminate-theory - type: refines - weight: 0.7 -- to: composite-progressive-damage - type: refines - weight: 0.7 -- to: pf-cohesive-zone - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Delamination & Cohesive Zone Models (CZM) - -## Summary - -Cohesive zone modeling (CZM) provides a continuous non-linear damage mechanics framework for simulating delamination and fracture process zones in composite laminates without requiring pre-existing crack-tip stress singularity assumptions. Material constitutive behavior is split into linear elasticity for bulk sub-domains and non-linear traction-separation relations along cohesive interfaces. Mode I delamination is governed by intrinsic traction-separation laws (TSL)—including exponential, bilinear, and trapezoidal models—parameterized by cohesive strength, critical separation displacement, and fracture energy. Finite element implementation utilizes zero-thickness cohesive zone elements (CZE) connecting adjacent bulk elements, formulating tangent stiffness matrices and nodal force vectors via global-to-local kinematic transformations. Experimental extraction of Mode I TSL from Double Cantilever Beam (DCB) testing utilizes the effective crack method and beam theory to derive closed-form crack-tip separation equations and direct differentiation of strain energy release rate curves. Furthermore, cohesive interface elements are integrated with phase-field continuum models to capture complex multi-scale failure interactions, such as delamination migration between plies. - -## 1. Core Concept - -Cohesive zone models embed non-linear material degradation along interface surfaces while maintaining linear elastic behavior in surrounding bulk sub-domains. In Mode I cleavage or delamination, the closing traction across the fracture process zone is dictated by a traction-separation law relating normal traction T (or sigma_c) to displacement jump delta (or delta_c). Key parameters defining the TSL include cohesive strength (peak stress sigma_cr or sigma_cu) and cohesive fracture energy G_c (or G_Ic), corresponding to the area under the traction-separation curve. Zero-thickness cohesive elements employ kinematic shape functions and localization matrices to interpolate nodal displacement jumps to Gauss integration points, transforming global degrees of freedom to element local coordinates for evaluating the tangent stiffness matrix and cohesive force vector. - -For experimental characterization, the modified direct method extracts Mode I TSL from DCB specimens without requiring non-linear finite element optimization loops. Combining corrected beam theory with the effective crack length concept, compliance measurements yield effective crack lengths that account for root rotation, shear deformation, and fracture process zone extension. A closed-form expression calculates crack-tip separation delta_c directly from applied load and specimen geometry, allowing Mode I strain energy release rate G_I to be differentiated with respect to delta_c to obtain tractions. Additionally, CZM is coupled with phase-field fracture frameworks by making cohesive toughness or separation limits dependent on local bulk phase-field damage variables, enabling objective modeling of delamination interacting with matrix cracking. - -## 2. Mathematical Formulation - -**Exponential Cohesive Traction-Separation Law** -$$ -T(\delta) = \sigma_{cr} \left( \frac{\delta}{\delta_{cr}} \right) \exp\left(1 - \frac{\delta}{\delta_{cr}}\right), \quad G_c = \sigma_{cr} \delta_{cr} \exp(1) -$$ -_Source: Alfano et al. - 2009 - Mode I fracture of adhesive joints using tailored cohesive zone models.pdf, Section 2.1, Eq. 4_ - -**Bilinear Cohesive Traction-Separation Law** -$$ -T(\delta) = \begin{cases} \gamma_1 \delta, & 0 \le \delta \le \Delta_{cr} \\ \sigma_{cr} \frac{\Delta_f - \delta}{\Delta_f - \Delta_{cr}}, & \Delta_{cr} < \delta \le \Delta_f \\ 0, & \delta > \Delta_f \end{cases}, \quad G_c = \frac{1}{2} \sigma_{cr} \Delta_f -$$ -_Source: Alfano et al. - 2009 - Mode I fracture of adhesive joints using tailored cohesive zone models.pdf, Section 2.2, Eqs. 5-6_ - -**Trapezoidal Cohesive Traction-Separation Law** -$$ -T(\delta) = \begin{cases} \gamma_1 \delta, & 0 \le \delta \le \Delta_{cr} = \lambda_1 \Delta_f \\ \sigma_{cr}, & \Delta_{cr} < \delta \le \Delta_2 = \lambda_2 \Delta_f \\ \sigma_{cr} \frac{\Delta_f - \delta}{\Delta_f - \Delta_2}, & \Delta_2 < \delta \le \Delta_f \\ 0, & \delta > \Delta_f \end{cases}, \quad G_c = \frac{1}{2} \sigma_{cr} \Delta_f (1 + \lambda_2 - \gamma_1) -$$ -_Source: Alfano et al. - 2009 - Mode I fracture of adhesive joints using tailored cohesive zone models.pdf, Section 2.3, Eqs. 7-8_ - -**4-Node Cohesive Zone Element Kinematics and Stiffness Matrix** -$$ -K = w \int_c B^T \left(\frac{\partial T}{\partial \delta}\right) B \, dc, \quad F_{Coh} = w \int_c B^T T \, dc -$$ -_Source: Alfano et al. - 2009 - Mode I fracture of adhesive joints using tailored cohesive zone models.pdf, Section 2.4, Eqs. 12, 17, 19_ - -**Modified Direct Method DCB Crack-Tip Separation** -$$ -\delta_c = \frac{12 P a_e}{E_1 b h} \left[ \left( \frac{a_e - a}{h} \right)^2 - \frac{E_1}{10 G_{13}} \right] -$$ -_Source: De Morais - 2024 - A new modified direct method for determining the mode I delamination traction-separation law.pdf, Section 2.1, Eqs. 4, 10_ - -**Phase-Field Coupling with Cohesive Interface Degradation** -$$ -D_{CE,eff} = \max\left\{D_{CE}, \, D_{d,up}, \, D_{d,low}\right\}, \quad D_d = 1 - \omega(d) -$$ -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.4, Eqs. 110-111_ - -**Notation:** -- T: Normal opening traction across cohesive interface -- \delta: Relative displacement jump (separation) across crack faces -- \sigma_{cr}: Critical peak stress / cohesive strength of the material -- \delta_{cr}: Displacement jump at peak stress -- \Delta_f: Final opening displacement jump at complete separation (zero traction) -- G_c: Critical strain energy release rate / cohesive fracture energy -- \gamma_1: Initial stiffness parameter of the cohesive traction-separation model -- \lambda_2: Shape parameter controlling plateau length in trapezoidal CZM -- u_g: Global nodal displacement vector for a 4-node cohesive element -- L: Operator localization matrix filtering relative nodal displacement pairs -- N(\xi): Shape function matrix evaluated at natural coordinate \xi -- R: Orthogonal coordinate transformation matrix from global to element local frame -- B: Strain-displacement matrix mapping global displacements to local jumps (B = R N L) -- P: Applied mechanical load in Double Cantilever Beam (DCB) test -- a: Initial crack length -- a_e: Effective crack length incorporating root rotation and process zone length -- C: Specimen compliance (C = \delta / P) -- b: Specimen width -- h: Thickness of individual DCB specimen leg -- E_1: Longitudinal elastic Young's modulus of composite substrate -- G_{13}: Through-thickness shear modulus of composite substrate -- \delta_c: Crack-tip opening displacement jump in DCB specimen -- G_I: Mode I strain energy release rate -- d: Phase-field damage variable ranging from 0 (intact) to 1 (fully broken) -- D_{CE,eff}: Effective cohesive element damage index coupled with bulk phase field - - -## 3. Algorithmic Implementation - -**ComputeCohesiveElementResStiff** -$$ -\begin{algorithmic} -\State $F_{Coh} = \text{zeros}(8, 1), \quad K_{elem} = \text{zeros}(8, 8)$ -\State $\xi_{gauss} = \left[-\frac{1}{\sqrt{3}}, \frac{1}{\sqrt{3}}\right], \quad w_{gauss} = [1.0, 1.0]$ -\State $L = \begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 & -1 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & -1 \\ 0 & 0 & 1 & 0 & -1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & -1 & 0 & 0 \end{bmatrix}$ -\For{$i = 1 \text{ To } 2$} -\State $\xi = \xi_{gauss}[i]$ -\State $N = \begin{bmatrix} \frac{1-\xi}{2} & 0 & \frac{1+\xi}{2} & 0 \\ 0 & \frac{1-\xi}{2} & 0 & \frac{1+\xi}{2} \end{bmatrix}$ -\State $R = \text{ComputeLocalRotationMatrix}(X_{elem}, \xi)$ -\State $B = R \cdot N \cdot L$ -\State $\delta_{local} = B \cdot u_g$ -\State $T_{local} = \text{ComputeCohesiveTraction}(\delta_{local}, \sigma_{cr}, G_c, \gamma_1)$ -\State $D_{local} = \text{ComputeCohesiveJacobian}(\delta_{local}, \sigma_{cr}, G_c, \gamma_1)$ -\State $dA = w \cdot \det(J(\xi)) \cdot w_{gauss}[i]$ -\State $F_{Coh} = F_{Coh} + (B^T \cdot T_{local}) \cdot dA$ -\State $K_{elem} = K_{elem} + (B^T \cdot D_{local} \cdot B) \cdot dA$ -\EndFor -\Return $F_{Coh}, K_{elem}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Alfano et al. - 2009 - Mode I fracture of adhesive joints using tailored cohesive zone models.pdf, Section 2.4, Eqs. 9-19_ - -**ExtractDCBModeITSL** -$$ -\begin{algorithmic} -\State $\text{tsl\_points} = []$ -\State $n_{pts} = \text{Length}(load\_disp\_data)$ -\For{$k = 1 \text{ To } n_{pts}$} -\State $P = load\_disp\_data[k].P, \quad \delta = load\_disp\_data[k].\delta, \quad C = \delta / P$ -\State $a_e = \frac{h}{2} \left( \frac{E_1 b C}{2} \right)^{1/3}$ -\State $G_I = \frac{12 P^2 a_e^2}{E_1 b^2 h^3}$ -\State $\delta_c = \frac{12 P a_e}{E_1 b h} \left[ \left(\frac{a_e - a}{h}\right)^2 - \frac{E_1}{10 G_{13}} \right]$ -\State $G_I\_list[k] = G_I, \quad \delta_c\_list[k] = \delta_c$ -\EndFor -\For{$k = 1 \text{ To } n_{pts}$} -\State $\sigma_c = \text{ComputeNumericalDerivative}(G_I\_list, \delta_c\_list, k)$ -\State $\text{tsl\_points.Append}((\delta_c\_list[k], G_I\_list[k], \sigma_c))$ -\EndFor -\Return $\text{tsl\_points}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: De Morais - 2024 - A new modified direct method for determining the mode I delamination traction-separation law.pdf, Section 2.1, Eqs. 4, 10, 12_ - - -## 4. Known Pitfalls - -- **cohesive-mesh-dependency-and-element-size-limit**: Cohesive zone elements require fine spatial discretization along the fracture process zone to avoid severe mesh size dependency and inaccurate load-displacement predictions; standard numerical practice requires inserting at least 3 or more cohesive elements within the non-linear process zone. _(Source: Alfano et al. - 2009 - Mode I fracture of adhesive joints using tailored cohesive zone models.pdf, Section 3.1)_ -- **trapezoidal-czm-damage-onset-overestimation**: Using a trapezoidal traction-separation law can overpredict structural load at damage onset compared to bilinear or exponential CZMs due to its altered interfacial stress profile, requiring a reduced cohesive strength parameter during calibration. _(Source: Alfano et al. - 2009 - Mode I fracture of adhesive joints using tailored cohesive zone models.pdf, Section 5)_ -- **anticlastic-bending-edge-delamination-bias**: Anticlastic bending in double cantilever beam legs generates non-uniform strain energy release rate distributions across the specimen width, causing crack initiation in the interior rather than at the edges and rendering single-edge displacement measurements unrepresentative of width-averaged crack-tip separation. _(Source: De Morais - 2024 - A new modified direct method for determining the mode I delamination traction-separation law.pdf, Section 1)_ -- **un-degraded-cohesive-element-delamination-migration-failure**: Failing to couple cohesive element damage degradation with adjacent bulk continuum phase-field damage variables prevents finite element models from capturing complex delamination migration phenomena across ply interfaces. _(Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.1.3, Fig. 19)_ - -## References - -- Alfano et al. - 2009 - Mode I fracture of adhesive joints using tailored cohesive zone models.pdf -- De Morais - 2024 - A new modified direct method for determining the mode I delamination traction-separation law.pdf -- Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/composite-failure-criteria.md b/packages/akms/src/akms/_bundled/global_nodes/composite-failure-criteria.md deleted file mode 100644 index 290c4ff..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/composite-failure-criteria.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -id: composite-failure-criteria -title: Composite Failure Criteria (Tsai-Wu, Hashin, Puck, LaRC) -domain: computational-mechanics -subdomain: composites -tags: -- composites -- failure-criteria -- tsai-wu -- hashin -- puck -- larc -status: established -confidence: 0.9 -source: hybrid -edges: -- to: composite-laminate-theory - type: requires - weight: 1.0 -- to: composite-progressive-damage - type: feeds-into - weight: 0.5 -- to: composite-delamination - type: refines - weight: 0.7 -- to: damage-continuum-framework - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Composite Failure Criteria (Tsai-Wu, Hashin, Puck, LaRC) - -## Summary - -Composite failure criteria establish mathematical bounds and activation rules for predicting damage initiation and catastrophic breakdown in heterogeneous composite constituents under multi-axial stress states. Failure modeling spans interactive macro-scale criteria—such as the 2D Tsai-Hill quadratic stress criterion used for First Ply Failure (FPF) assessments—and mode-specific constituent criteria, such as the Hashin fiber failure criterion based on combined axial and shear stress components. In progressive damage and multiscale frameworks, failure criteria dictate local constituent stiffness reduction (e.g., zeroing fiber stiffness upon reaching critical thresholds) or drive continuum phase-field damage evolution using activation flag parameters that enforce threshold-triggered damage propagation. - -## 1. Core Concept - -Failure criteria define thresholds at which material points transition from linear elastic or elastic-degradable behavior to irreversible damage or total loss of load-carrying capacity. In macro-scale lamina modeling, interactive stress criteria like Tsai-Hill formulate a single scalar failure index by combining longitudinal, transverse, and shear stress components relative to allowable material strengths. While effective for FPF prediction, interactive quadratic criteria do not distinguish between distinct micro-mechanical failure modes. - -In micromechanical and multiscale progressive failure frameworks, failure criteria are applied directly at constituent length scales. For fiber constituents (e.g., carbon fibers), the Hashin failure criterion evaluates a quadratic index combining longitudinal axial stress and out-of-plane/in-plane shear stresses. Upon reaching unity, brittle fiber failure is triggered and local stiffness is zeroed. For matrix constituents, hydrostatic stress thresholds govern thermoelastic progressive degradation driven by thermal residual cooling stresses. Furthermore, physically-based or empirical criteria (such as Puck's criterion) can be integrated into variational phase-field fracture formulations by introducing an activation flag parameter P that multiplies the driving strain energy, ensuring phase-field evolution commences only after the critical failure boundary is crossed. - -## 2. Mathematical Formulation - -**Hashin Fiber Brittle Failure Criterion** -$$ -h = \left(\frac{\sigma_{11}}{\sigma_{\text{axial}}}\right)^2 + \frac{1}{s_{\text{axial}}^2} \left(\sigma_{13}^2 + \sigma_{12}^2\right) \ge 1 -$$ -_Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.2, Eq. 18_ - -**Tsai-Hill 2D First Ply Failure Criterion** -$$ -\frac{\sigma_{11}^2}{X^2} - \frac{\sigma_{11} \sigma_{22}}{X^2} + \frac{\sigma_{22}^2}{Y^2} + \frac{\sigma_{12}^2}{S^2} \ge 1 -$$ -_Source: Cumbo et al_2022_Design allowables of composite laminates.pdf, Section Common damage/failure modelling embedded in software solutions, Eq. 5_ - -**Phase-Field Failure Criterion Activation Flag Coupling** -$$ -F = -\omega'(d) P H - \frac{G_c}{c_0} \left( \frac{\alpha'(d)}{l_0} - 2 l_0 \Delta d \right) \le 0 -$$ -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.6, Eq. 130_ - -**Thermoelastic Matrix Microcrack Initiation Criterion** -$$ -\sigma_{\text{eq}} \ge r_{\text{crit}}(\dot{\epsilon}, T), \quad \sigma = (1 - \phi) C (\epsilon - \alpha \Delta T) -$$ -_Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.2, Eqs. 1-2_ - -**Notation:** -- h: Hashin fiber failure index -- \sigma_{11}, \sigma_{22}: Longitudinal and transverse normal stress components -- \sigma_{12}, \sigma_{13}: Shear stress components -- \sigma_{\text{axial}}, s_{\text{axial}}: Fiber axial normal and shear allowable strengths -- X, Y, S: Lamina longitudinal, transverse, and shear allowable strengths -- P: Failure criterion activation flag parameter (0 or 1) -- H: Historical driving strain energy density -- d: Phase-field damage variable -- G_c: Critical strain energy release rate -- l_0: Phase-field internal length scale parameter -- c_0: Phase-field geometric normalization constant -- \sigma_{\text{eq}}: Hydrostatic equivalent stress in matrix -- r_{\text{crit}}: Critical threshold stress for matrix damage initiation -- \phi: Scalar damage variable scaling matrix stiffness -- \alpha: Coefficient of thermal expansion -- \Delta T: Temperature change relative to reference state - - -## 3. Algorithmic Implementation - -**EvaluateHashinFiberFailure** -$$ -\begin{algorithmic} -\State $h = \left(\frac{\sigma_{11}}{\sigma_{\text{axial}}}\right)^2 + \frac{1}{s_{\text{axial}}^2} \left(\sigma_{13}^2 + \sigma_{12}^2\right)$ -\If{$h \ge 1.0$} -\State $\text{failed} = \text{True}, \quad C_{\text{fiber}} = 0$ -\Else -\State $\text{failed} = \text{False}$ -\EndIf -\Return $h, \text{failed}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.2, Eq. 18_ - -**EvaluatePhaseFieldActivationFlag** -$$ -\begin{algorithmic} -\If{$\text{criterion\_met} == \text{True}$} -\State $P = 1.0$ -\Else -\State $P = 0.0$ -\EndIf -\State $H_{\text{eff}} = P \cdot H$ -\State $F = -\omega'(d) H_{\text{eff}} - \frac{G_c}{c_0} \left( \frac{\alpha'(d)}{l_0} - 2 l_0 \Delta d \right)$ -\Return $F, P$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.6, Eq. 130_ - - -## 4. Known Pitfalls - -- **unrealistic-sudden-damage-jump-activation-flag**: Multiplying an activation flag parameter P to the historical driving energy H in phase-field formulations keeps the driving force zero until the failure criterion is met; upon activation, the unchanged driving force is suddenly applied, which can cause an unrealistic sudden increase in the phase field variable and yield inaccurate crack evolution mechanics. _(Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.6)_ -- **ignoring-thermal-cool-down-damage-overestimates-stiffness**: Neglecting thermal residual stresses and matrix microcracking induced during cool-down from manufacturing temperatures (due to CTE mismatch between fiber and matrix) results in an overprediction of the initial tensile stiffness of the composite laminate by 25% or more. _(Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 3)_ -- **first-ply-failure-indicator-lacks-mode-differentiation**: Quadratic failure criteria such as 2D Tsai-Hill combine multiple stress components into a single scalar failure index to predict damage onset, but fail to differentiate between specific failure modes (e.g., fiber breakage vs. matrix cracking), preventing accurate post-initiation progressive degradation modeling without secondary mode identification rules. _(Source: Cumbo et al_2022_Design allowables of composite laminates.pdf, Section Common damage/failure modelling embedded in software solutions)_ - -## References - -- Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf -- Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf -- Cumbo et al_2022_Design allowables of composite laminates.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/composite-homogenization.md b/packages/akms/src/akms/_bundled/global_nodes/composite-homogenization.md deleted file mode 100644 index 0545dbc..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/composite-homogenization.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -id: composite-homogenization -title: Composite Homogenization & Micromechanics -domain: computational-mechanics -subdomain: composites -tags: -- composites -- homogenization -- mori-tanaka -- RVE -- voigt-reuss -- hashin-shtrikman -status: established -confidence: 0.9 -source: hybrid -edges: -- to: elastic-anisotropic - type: requires - weight: 1.0 -- to: composite-laminate-theory - type: feeds-into - weight: 0.5 -- to: tensor-products-contractions - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Composite Homogenization & Micromechanics - -## Summary - -Composite homogenization and micromechanics establish mathematical frameworks to bridge constitutive behavior across microstructural constituent length scales (fibers, matrix, voids, woven tows) and macroscopic effective properties. Analytical micromechanics formulates exact and variational bounds—such as Hashin's concentric composite sphere model for bulk and shear moduli—and integral equation schemes including the Effective Field Method (EFM), Mori-Tanaka Method (MTM), and Additive General Integral Equations (AGIE) applicable to both local and peridynamic media. Numerical homogenization utilizes Representative Volume Elements (RVE) or Representative Unit Cells (RUC) subjected to volume-weighted field averaging of local stress and strain fields. Generalized RVE theory establishes stabilization thresholds under self-equilibrated compact-support body forces, eliminating sample size and boundary layer edge effects. - -## 1. Core Concept - -Homogenization determines effective macro-scale constitutive properties by performing volume averages over Representative Volume Elements (RVE) or Representative Unit Cells (RUC) that characterize the geometric and mechanical heterogeneity of constituent phases. In Hashin's classical composite sphere model, two-phase heterogeneous media are modeled as concentric spherical elements preserving inclusion volume concentration c = (a_n / b_n)^3. Applying uniform radial stress or displacement boundary conditions yields closed-form expressions for the effective bulk modulus K*, where upper and lower variational bounds derived via minimum complementary and potential energy principles coincide. - -In advanced continuum and nonlocal micromechanics, field distributions across inclusions are governed by Additive General Integral Equations (AGIE) that relate local perturbed fields to self-equilibrated body forces without requiring specific constitutive laws. For periodic or random microstructures, translated averaging over an RVE or periodic grid eliminates artificial boundary layer distortions. In 3D woven fabric composites, finite element unit cell homogenization applies periodic or uniform kinematic boundary conditions to solve local equilibrium, subsequently computing macroscopic stresses Sigma_ij and strains E_ij via volume integration over the RUC to extract the effective anisotropic stiffness or compliance matrix S*. - -## 2. Mathematical Formulation - -**Hashin Composite Sphere Variational Bulk Modulus** -$$ -K^* = K_m \left[ 1 + \frac{(K_p - K_m)(4 G_m + 3 K_m)c}{K_m(4 G_m + 3 K_p) - 4 G_m (K_m - K_p) c} \right], \quad \frac{K^*}{K_m} = 1 + 3(1 - \nu_m) \sum_{i=1}^k \frac{\left(\frac{K_p^{(i)}}{K_m} - 1\right)c_i}{2(1 - 2\nu_m) + (1 + \nu_m)\left[\frac{K_p^{(i)}}{K_m} - \left(\frac{K_p^{(i)}}{K_m} - 1\right)c\right]} -$$ -_Source: Hashin - THE ELASTIC MODULI OF HETEROGENEOUS MATERIALS.pdf, Section 3, Eqs. 3.12, 3.20, 3.22_ - -**Additive General Integral Equation (AGIE)** -$$ -\langle \vartheta \rangle_i(z) = \vartheta^{b(0)}(z) + \int \mathcal{L}_j^{\theta\zeta}(z - x_j, \zeta) \phi(v_j, x_j | v_1, x_1) \, dx_j -$$ -_Source: Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf, Section 3.4, Eq. 3.23_ - -**Woven Composite Unit Cell Field Averaging and Compliance Matrix** -$$ -\Sigma_{ij} = \frac{1}{V_{\text{RUC}}} \int_{V_{\text{RUC}}} \sigma_{ij} \, dV, \quad E_{ij} = \frac{1}{V_{\text{RUC}}} \int_{V_{\text{RUC}}} \varepsilon_{ij} \, dV, \quad E_{ij} = S_{ijkl}^* \Sigma_{kl} -$$ -_Source: Carvelli and Poggi - 2001 - A homogenization procedure for the numerical analysis of woven fabric composites.pdf, Section 2 & 3, Eqs. 1-8_ - -**Translated Averaging and Compact Body Force RVE Stabilization** -$$ -\langle \{\cdot\} \rangle(x) = \frac{1}{V_x} \int_{V_x} \{\cdot, \chi\} \, d\chi, \quad \langle u \rangle(x) = u_\infty \equiv \text{const} \quad \forall |x| \ge B_{\text{RVE}} -$$ -_Source: Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf, Section 5 & 8.3, Eqs. 4.21, 5.6_ - -**Notation:** -- K^*: Homogenized effective bulk modulus of heterogeneous material -- K_m, G_m, \nu_m: Bulk modulus, shear modulus, and Poisson's ratio of matrix phase -- K_p, K_p^{(i)}: Bulk modulus of inclusion phase (or i-th inclusion phase) -- c, c_i: Volume fraction / concentration of inclusion phase(s) -- \vartheta: Local relative field jump vector / tensor -- \mathcal{L}_j^{\theta\zeta}: Single-inclusion perturbation operator mapping effective fields to local fields -- \phi(v_j, x_j | v_1, x_1): Conditional probability density for finding inclusion v_j given v_1 -- \Sigma_{ij}, E_{ij}: Macroscopic volume-averaged stress and strain tensors -- S_{ijkl}^*: Macroscopic effective orthotropic compliance tensor -- V_{\text{RUC}}: Spatial volume of 3D repeating unit cell -- \sigma_{ij}, \varepsilon_{ij}: Local microscopic/mesoscopic stress and strain field tensors -- B_{\text{RVE}}: Stabilization radius defining Representative Volume Element boundaries - - -## 3. Algorithmic Implementation - -**ComputeHashinSphericalBounds** -$$ -\begin{algorithmic} -\State $\text{total\_c} = 0.0$ -\For{$i = 1 \text{ To } k$} -\State $\text{total\_c} = \text{total\_c} + c_i$ -\EndFor -\State $\text{sum\_term} = 0.0$ -\For{$i = 1 \text{ To } k$} -\State $\text{num} = \left( \frac{K_p^{(i)}}{K_m} - 1.0 \right) c_i$ -\State $\text{den} = 2.0 (1.0 - 2.0 \nu_m) + (1.0 + \nu_m) \left[ \frac{K_p^{(i)}}{K_m} - \left( \frac{K_p^{(i)}}{K_m} - 1.0 \right) \text{total\_c} \right]$ -\State $\text{sum\_term} = \text{sum\_term} + \frac{\text{num}}{\text{den}}$ -\EndFor -\State $K^* = K_m \left( 1.0 + 3.0 (1.0 - \nu_m) \text{sum\_term} \right)$ -\Return $K^*$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Hashin - THE ELASTIC MODULI OF HETEROGENEOUS MATERIALS.pdf, Section 3, Eq. 3.22_ - -**HomogenizeWovenUnitCell** -$$ -\begin{algorithmic} -\State $S^* = \text{zeros}(6, 6)$ -\State $V_{\text{RUC}} = \text{ComputeRUCVolume}(\text{mesh\_nodes}, \text{mesh\_elements})$ -\For{$k = 1 \text{ To } 6$} -\State $\Sigma_k = \text{applied\_macro\_stresses}[k]$ -\State $\text{BCs} = \text{ApplyPeriodicKinematicBCs}(\text{mesh\_nodes}, \Sigma_k)$ -\State $\sigma_{\text{local}}, \varepsilon_{\text{local}} = \text{SolveFEAEquilibrium}(\text{mesh\_nodes}, \text{mesh\_elements}, \text{BCs})$ -\State $E_k = \text{zeros}(6, 1)$ -\For{$e = 1 \text{ To } n_{\text{elem}}$} -\State $dV = \text{ComputeElementVolume}(e)$ -\State $\varepsilon_e = \text{GetElementAverageStrain}(e, \varepsilon_{\text{local}})$ -\State $E_k = E_k + \varepsilon_e \cdot dV$ -\EndFor -\State $E_k = \frac{E_k}{V_{\text{RUC}}}$ -\For{$j = 1 \text{ To } 6$} -\State $S^*[j, k] = \frac{E_k[j]}{\Sigma_k[k]}$ -\EndFor -\EndFor -\Return $S^*$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Carvelli and Poggi - 2001 - A homogenization procedure for the numerical analysis of woven fabric composites.pdf, Section 3, Eqs. 1-8_ - - -## 4. Known Pitfalls - -- **voigt-reuss-bounds-lack-phase-geometry**: Voigt and Reuss bounds rely solely on phase volume fractions and ignore microstructural geometry, resulting in wide bounds; Hashin composite sphere concentric models provide tight exact bounds by accounting for inclusion spherical geometry and matrix continuity. _(Source: Hashin - THE ELASTIC MODULI OF HETEROGENEOUS MATERIALS.pdf, Section 3)_ -- **boundary-layer-edge-effects-in-rve-estimation**: Determining RVE size under remote uniform loading introduces severe boundary layer and sample size edge effects; applying self-equilibrated compact-support body forces stabilizes displacement fields outside a characteristic radius B_RVE and eliminates edge artifacts. _(Source: Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf, Section 8.3, Eq. 4.21)_ -- **constant-subcell-strain-elimination-gmc**: In GMC micromechanics theory, the constant strain field assumption within a subcell causes any subcell assigned approximately zero stiffness (e.g., a void) to eliminate the entire row and column in which it resides during homogenization unless modeled via a sub-RUC. _(Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.1)_ - -## References - -- Hashin - THE ELASTIC MODULI OF HETEROGENEOUS MATERIALS.pdf -- Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf -- Carvelli and Poggi - 2001 - A homogenization procedure for the numerical analysis of woven fabric composites.pdf -- Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/composite-laminate-theory.md b/packages/akms/src/akms/_bundled/global_nodes/composite-laminate-theory.md deleted file mode 100644 index 9536547..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/composite-laminate-theory.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -id: composite-laminate-theory -title: Classical Laminate Theory (CLT) -domain: computational-mechanics -subdomain: composites -tags: -- composites -- laminate -- ABD-matrix -- fiber-reinforced -- kirchhoff-love -status: established -confidence: 0.9 -source: hybrid -edges: -- to: elastic-anisotropic - type: requires - weight: 1.0 -- to: composite-failure-criteria - type: feeds-into - weight: 0.5 -- to: composite-progressive-damage - type: feeds-into - weight: 0.5 -- to: composite-delamination - type: contradicts - weight: 0.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Classical Laminate Theory (CLT) - -## Summary - -Composite laminate analysis characterizes the multi-axial thermoelastic mechanical behavior, stress distributions, and design allowables of stacked fiber-reinforced plies under mechanical and thermal environments. Constitutive modeling at meso- and macro-scales incorporates additive thermoelastic strain decomposition to account for thermal expansion mismatches between constituents during manufacturing cool-down, which generate initial microcracking and residual stress states across plies. Lamina constitutive laws are expressed via transversely isotropic Gibbs free energy formulations, providing energy components for longitudinal, transverse, and shear stress invariants. On the structural level, laminate strength prediction and design allowable generation rely on building-block testing frameworks, utilizing statistical methods such as the Lamina Variability Method (LVM) to compute B-basis allowables or finite fracture mechanics to model open-hole notched strength based on coupled stress-energy criteria. - -## 1. Core Concept - -Laminated composite mechanics integrates constitutive responses across length scales—from constituent fibers and matrix to individual unidirectional or woven plies, up to multi-ply structural laminates. At the lamina level, plies are represented as homogenized transversely isotropic media governed by elasticity and thermal expansion tensors. During thermal processing (such as chemical vapor infiltration cool-down), CTE mismatches between reinforcement fibers and matrix constituents produce severe interlaminar and intralaminar residual stresses, initiating matrix microcracks that reduce initial laminate tensile stiffness by over 25% relative to uncracked pristine states. - -Progressive failure and design allowables in composite laminates are evaluated across the building block hierarchy. Unnotched and open-hole notched laminate strengths are predicted by coupling lamina-level strength allowables with progressive damage or finite fracture mechanics models. To reduce testing requirements for certification, statistical data-reduction methodologies like the Lamina Variability Method (LVM) pool lamina-level variance data with reduced laminate test sets to establish A- and B-basis allowables without requiring exhaustive physical testing campaigns at every stacking sequence. - -## 2. Mathematical Formulation - -**Thermoelastic Constitutive Law with Matrix Damage** -$$ -\sigma = (1 - \phi) C (\epsilon - \alpha \Delta T) = (1 - \phi) C \epsilon^e -$$ -_Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.2, Eq. 2_ - -**Transversely Isotropic Lamina Gibbs Free Energy Decomposition** -$$ -\psi(\tilde{\sigma}) = \frac{1}{2} \left[ \frac{\tilde{\sigma}_L^2}{E_{11}} - \frac{4 \nu_{12} \tilde{\sigma}_L \tilde{p}_T}{E_{11}} + \frac{\tilde{p}_T^2}{E_T} + \frac{\tilde{\tau}_T^2}{G_T} + \frac{\tilde{\tau}_L^2}{G_{12}} \right] -$$ -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.6, Eqs. 123-125_ - -**Lamina Variability Method (LVM) B-Basis Allowable Factor** -$$ -k_{\text{LVM}} = 1 - K(N_1, N_2) \cdot \text{CV}_2, \quad X_{\text{basis}} = k_{\text{LVM}} \bar{X}_1 -$$ -_Source: Cumbo et al_2022_Design allowables of composite laminates.pdf, Section Statistical approaches based on laminate-level data, Eqs. 3-4_ - -**Coupled Stress-Energy Criterion for Open-Hole Notched Laminate Strength** -$$ -\frac{1}{l} \int_{R}^{R+l} \sigma_{xx}(0, y) \, dy = X_L, \quad \frac{1}{l} \int_{R}^{R+l} G_I(a) \, da = G_{IC} -$$ -_Source: Cumbo et al_2022_Design allowables of composite laminates.pdf, Section Simulation-based approach supported by a reduced number of tests, Eq. 6_ - -**Notation:** -- \sigma: Cauchy stress tensor -- \epsilon, \epsilon^e: Total strain tensor and elastic strain tensor -- \alpha: Coefficient of thermal expansion tensor -- \Delta T: Temperature differential relative to reference stress-free state -- \phi: Scalar damage degradation parameter -- \psi(\tilde{\sigma}): Gibbs free energy density function -- \tilde{\sigma}_L, \tilde{p}_T: Longitudinal stress and transverse hydrostatic stress invariants -- \tilde{\tau}_L, \tilde{\tau}_T: Longitudinal shear and transverse shear stress invariants -- E_{11}, E_{22}: Longitudinal and transverse Young's moduli -- G_{12}, G_{23}: In-plane shear modulus and transverse shear modulus -- \nu_{12}, \nu_{23}: Poisson's ratios -- k_{\text{LVM}}: Lamina Variability Method reduction factor -- X_{\text{basis}}: B-basis design allowable strength -- X_L: Unnotched laminate tensile strength allowable -- G_{IC}: Critical Mode I strain energy release rate -- l: Characteristic fracture distance in notched laminates - - -## 3. Algorithmic Implementation - -**EvaluateLaminateThermoelasticResidualStress** -$$ -\begin{algorithmic} -\State $\Delta T = T_{\text{room}} - T_{\text{manufacture}}$ -\For{$k = 1 \text{ To } n_{\text{plies}}$} -\State $\epsilon^t_k = \alpha_k \cdot \Delta T$ -\State $\sigma_k = C_k \cdot (\epsilon_{\text{laminate}} - \epsilon^t_k)$ -\State $\sigma_{\text{eq}, k} = \text{ComputeEquivalentHydrostaticStress}(\sigma_k)$ -\If{$\sigma_{\text{eq}, k} \ge r_{\text{crit}}$} -\State $\phi_k = \text{UpdateMatrixDamageScalar}(\sigma_k, \phi_k)$ -\State $\sigma_k = (1.0 - \phi_k) \cdot C_k \cdot (\epsilon_{\text{laminate}} - \epsilon^t_k)$ -\EndIf -\EndFor -\Return $\sigma_{\text{laminate}}, \phi_{\text{plies}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.2, Eqs. 1-2_ - -**ComputeLVMDesignAllowable** -$$ -\begin{algorithmic} -\State $\text{CV}_2 = \frac{S_2}{\bar{X}_2}$ -\State $K_{\text{factor}} = \text{LookupToleranceFactor}(N_1, N_2)$ -\State $k_{\text{LVM}} = 1.0 - K_{\text{factor}} \cdot \text{CV}_2$ -\State $X_{\text{basis}} = k_{\text{LVM}} \cdot \bar{X}_1$ -\Return $X_{\text{basis}}, k_{\text{LVM}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Cumbo et al_2022_Design allowables of composite laminates.pdf, Section Statistical approaches based on laminate-level data, Eqs. 3-4_ - - -## 4. Known Pitfalls - -- **ignoring-thermal-cool-down-residual-stress**: Neglecting thermal residual stresses and matrix microcracking induced during post-manufacturing cool-down (due to CTE mismatch between fiber and matrix constituents) results in overpredicting the initial tensile modulus of composite laminates by 25% or more. _(Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 3)_ -- **lamina-variability-method-failure-mode-shift**: Using the Lamina Variability Method (LVM) to calculate laminate B-basis design allowables assumes that failure modes and covariance do not shift significantly between lamina and laminate test levels; if failure modes change across stacking sequences, LVM underpredicts allowable knockdowns and full CMH-17 testing protocol must be used. _(Source: Cumbo et al_2022_Design allowables of composite laminates.pdf, Section Statistical approaches based on laminate-level data)_ -- **single-layer-ply-element-delamination-migration-incapability**: Modeling each lamina using a single layer of continuum elements linked by inter-ply cohesive interface elements cannot capture intra-ply damage gradients or delamination migration across ply interfaces unless multiple continuum element layers per ply or coupled phase-field interface models are employed. _(Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.1.3 & 3.4, Fig. 19)_ - -## References - -- Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf -- Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf -- Cumbo et al_2022_Design allowables of composite laminates.pdf -- Carvelli and Poggi - 2001 - A homogenization procedure for the numerical analysis of woven fabric composites.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/composite-progressive-damage.md b/packages/akms/src/akms/_bundled/global_nodes/composite-progressive-damage.md deleted file mode 100644 index 6d1738c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/composite-progressive-damage.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: composite-progressive-damage -title: Progressive Damage in Composite Plies -domain: computational-mechanics -subdomain: composites -tags: -- composites -- progressive-damage -- MPDM -- CDM -- mesh-regularization -status: established -confidence: 0.9 -source: hybrid -edges: -- to: composite-failure-criteria - type: requires - weight: 1.0 -- to: composite-laminate-theory - type: requires - weight: 1.0 -- to: damage-continuum-framework - type: refines - weight: 0.7 -- to: damage-nonlocal-gradient - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Progressive Damage in Composite Plies - -## Summary - -Progressive damage in composite plies characterizes the non-linear degradation of constituent elastic stiffness due to gradually accumulated microcracks, fiber-matrix debonding, and fiber breakage. Rather than assuming abrupt zeroing of moduli (ply-discount models), continuum damage mechanics (CDM) and variational phase-field frameworks model continuous material softening. In multiscale thermoelastic formulations, matrix microcracking is governed by hydrostatic stress/strain thresholds and driven by thermal CTE mismatches during manufacturing cool-down, scaling the elastic stiffness matrix via a scalar damage parameter. On the lamina level, regularized diffusive phase-field models describe crack nucleation and growth across length scales by decomposing strain energy into mode-specific components (fiber failure, matrix cracking, and longitudinal/transverse shear) and enforcing damage irreversibility using historical strain energy fields. - -## 1. Core Concept - -Progressive damage models capture post-initiation material degradation across microstructural and continuum length scales. In multiscale constituent frameworks, quasi-brittle matrix subcells undergo progressive degradation governed by hydrostatic equivalent stress and strain invariants. Once equivalent hydrostatic stress exceeds a temperature- and strain-rate-dependent threshold, a scalar damage parameter scales the elastic stiffness tensor, allowing subcells to continue carrying load during microcrack evolution. Thermal residual stresses from post-manufacturing cool-down initiate microcracking prior to mechanical loading, reducing initial laminate tensile modulus by over 25%. - -In regularized phase-field fracture, progressive damage is modeled diffusively using an auxiliary phase-field variable ranging from intact to fully broken states over an internal length scale. Irreversibility is guaranteed by tracking the maximum historical strain energy density. To capture strong anisotropic failure behavior in unidirectional plies, strain energy is decomposed into constituent mode-specific components governing fiber breakage, matrix cracking, in-plane shear, and transverse shear, preventing unphysical damage coupling. - -## 2. Mathematical Formulation - -**Thermoelastic Continuum Damage Constitutive Relation** -$$ -\sigma = (1 - \phi) C (\epsilon - \alpha \Delta T) = (1 - \phi) C \epsilon^e -$$ -_Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.2, Eq. 2_ - -**Incremental Matrix Damage Evolution Law** -$$ -d k_{n+1} = \frac{n \, dK_0(T_{n+1}) \left[ e^n_{\text{eq}} - \alpha_0(T_n) \Delta T_n \right] + K_0(T_n) \left[ d e^{n+1}_{\text{eq}} - \alpha_0(T_n) d\Delta T_{n+1} - d\alpha_0(T_{n+1}) \Delta T_n \right] - k_n K_0(T_n) \left[ d e^{n+1}_{\text{eq}} - \alpha_0(T_n) d\Delta T_{n+1} - d\alpha_0(T_{n+1}) \Delta T_n \right]}{K_0(T_n) \left[ e^n_{\text{eq}} - \alpha_0(T_n) \Delta T_n \right]} -$$ -_Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.2, Eq. 17_ - -**Phase-Field Diffusive Damage Evolution with Viscous Regularization** -$$ -2 (1 - d) H - G_c \left( \frac{d}{l_0} - l_0 \Delta d \right) = \eta \dot{d} -$$ -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 2.3, Eq. 40_ - -**Mode-Specific Anisotropic Energy Decomposition for Composite Plies** -$$ -\psi_{11} = \frac{\langle \tilde{\sigma}_L \rangle_+^2}{2 E_{11}}, \quad \psi_{22} = \frac{\langle \tilde{p}_T \rangle_+^2}{2 E_T}, \quad \psi_{12} = \frac{\tilde{\tau}_L^2}{2 G_{12}}, \quad \psi_{23} = \frac{\tilde{\tau}_T^2}{2 G_T} -$$ -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.6, Eqs. 126-129_ - -**Notation:** -- \sigma: Second-order Cauchy stress tensor -- \epsilon, \epsilon^e: Total strain tensor and elastic strain tensor -- \phi: Scalar damage variable scaling matrix stiffness (0 <= \phi <= 1) -- k: Residual stiffness factor (k = 1 - \phi) -- C: Fourth-order linear elastic stiffness tensor -- \alpha, \alpha_0: Coefficient of thermal expansion tensor and matrix CTE -- \Delta T: Temperature differential relative to stress-free manufacturing state -- e_{\text{eq}}: Hydrostatic equivalent strain invariant -- K_0: Undamaged bulk modulus -- n: Damaged normalized secant modulus parameter -- d: Phase-field damage variable ranging from 0 (intact) to 1 (fully degraded) -- H: Historical driving strain energy density enforcing damage irreversibility -- G_c: Critical strain energy release rate -- l_0: Internal length scale parameter controlling diffusive crack width -- \eta: Viscous regularization parameter -- \psi_{11}, \psi_{22}, \psi_{12}, \psi_{23}: Strain energy components corresponding to constituent failure modes - - -## 3. Algorithmic Implementation - -**UpdateThermoelasticMatrixDamage** -$$ -\begin{algorithmic} -\State $e^n_{\text{eq}} = \text{ComputeHydrostaticStrain}(\epsilon_n)$ -\State $r^n_{\text{eq}} = 3 k_n K_0(T_n) \left[ e^n_{\text{eq}} - \alpha_0(T_n) \Delta T_n \right]$ -\If{$r^n_{\text{eq}} \ge r_{\text{crit}}(T_n)$} -\State $d e^{n+1}_{\text{eq}} = e^{n+1}_{\text{eq}} - e^n_{\text{eq}}$ -\State $d k_{n+1} = \frac{n \, dK_0(T_{n+1}) \left[ e^n_{\text{eq}} - \alpha_0(T_n) \Delta T_n \right] + K_0(T_n) \left[ d e^{n+1}_{\text{eq}} - \alpha_0 d\Delta T_{n+1} \right] - k_n K_0(T_n) \left[ d e^{n+1}_{\text{eq}} - \alpha_0 d\Delta T_{n+1} \right]}{K_0(T_n) \left[ e^n_{\text{eq}} - \alpha_0(T_n) \Delta T_n \right]}$ -\State $k_{n+1} = k_n + d k_{n+1}$ -\State $\phi_{n+1} = 1.0 - k_{n+1}$ -\Else -\State $\phi_{n+1} = \phi_n$ -\EndIf -\State $\sigma_{n+1} = (1.0 - \phi_{n+1}) C(T_{n+1}) (\epsilon_{n+1} - \alpha_0 \Delta T_{n+1})$ -\Return $\sigma_{n+1}, \phi_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.2, Eqs. 2, 17_ - -**ExplicitPhaseFieldDamageUpdate** -$$ -\begin{algorithmic} -\State $\psi_+ = \text{ComputeTensileStrainEnergy}(\epsilon_n)$ -\State $H_{n+1} = \max\left(H_n, \, \psi_+\right)$ -\State $Y = -2 (1 - d_n) H_{n+1} N^d - \frac{G_c}{c_0} \left[ \frac{\alpha'(d_n)}{l_0} N^d + 2 l_0 B^d \nabla d_n \right]$ -\State $\dot{d}_{n+1} = \frac{Y}{\eta}$ -\State $d_{n+1} = d_n + \Delta t \cdot \dot{d}_{n+1}$ -\If{$d_{n+1} > 1.0$} -\State $d_{n+1} = 1.0$ -\EndIf -\Return $d_{n+1}, H_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 2.3 & 2.6, Eqs. 40, 56, 61_ - - -## 4. Known Pitfalls - -- **ignoring-thermal-cooling-damage-overestimates-stiffness**: Neglecting progressive matrix microcracking during manufacturing thermal cool-down leads to overestimating initial tensile stiffness of composite laminates by at least 25%. _(Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 3)_ -- **artificial-viscosity-oversmoothing-dynamic-crack**: In rate-dependent viscous phase-field formulations, choosing an excessively large artificial viscosity parameter eta to stabilize time integration over-damps crack evolution, widening the degraded process zone beyond physical bounds during dynamic crack growth. _(Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 2.3)_ -- **uncoupled-fiber-matrix-anisotropic-phasefield-inaccuracy**: In homogenized lamina phase-field models, failing to separate fiber and matrix strain energy contributions into distinct mode-specific degradation functions results in unphysical coupling of fiber breakage and matrix cracking, leading to inaccurate crack path predictions. _(Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.1.2 & 3.6)_ - -## References - -- Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf -- Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf -- Cumbo et al_2022_Design allowables of composite laminates.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/constit-elastic-predictor.md b/packages/akms/src/akms/_bundled/global_nodes/constit-elastic-predictor.md deleted file mode 100644 index bee1711..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/constit-elastic-predictor.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: constit-elastic-predictor -title: Elastic Trial State Computation -domain: computational-mechanics -subdomain: constitutive -tags: -- constitutive -- elastic-predictor -- trial-stress -- plasticity -- return-mapping -status: established -confidence: 0.9 -source: hybrid -edges: -- to: constit-stress-update-architecture - type: requires - weight: 1.0 -- to: kinematics-multiplicative-decomp - type: requires - weight: 0.8 -- to: plasticity-general-return-mapping - type: feeds-into - weight: 1.0 -- to: plasticity-von-mises - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Elastic Trial State Computation - -## Summary - -Elastic trial state computation forms the operator-split prediction phase in elastoplastic state determination, freezing plastic flow to evaluate candidate stress and yield function admissibility. - -## 1. Core Concept - -The elastic predictor step freezes all plastic internal state variables and evaluates a trial stress state based on the assumption that the given strain increment is entirely elastic. In small-strain formulations, the elastic trial stress is computed from the linear elastic stiffness tensor and strain increment. In finite-strain multiplicative hyperelastic formulations, the elastic trial state is computed in the spatial configuration using the elastic left Cauchy-Green tensor and trial Kirchhoff stress. Evaluating the trial yield function against this elastic trial stress determines whether the material remains elastic or requires a plastic return-mapping correction. - -## 2. Mathematical Formulation - -**Infinitesimal Elastic Trial Stress** -$$ -\bm{\sigma}^{tr} = \bm{\sigma}^n + \mathbf{D}^e : \Delta \bm{\varepsilon} -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 260, 271_ - -**Infinitesimal Trial Yield Function** -$$ -f^{tr} = f(\bm{\sigma}^{tr}, \bm{q}_n) = \|\bm{s}^{tr} - \bm{\alpha}_n\| - \sqrt{\frac{2}{3}} \sigma_y(\bar{\varepsilon}^p_n) -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.2, p. 124_ - -**Finite-Strain Trial Elastic Left Cauchy-Green Tensor** -$$ -\bm{b}_e^{tr} = \bm{f} \cdot \bm{b}_e^n \cdot \bm{f}^T -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 9.1, p. 320; Kim_FEA for Elastoplastic Problems.pdf p. 293, 294_ - -**Finite-Strain Trial Kirchhoff Stress** -$$ -\bm{\tau}^{tr} = 2 \frac{\partial \Psi(\bm{b}_e^{tr})}{\partial \bm{b}_e^{tr}} \cdot \bm{b}_e^{tr} = p_{n+1}^{tr} J_{n+1} \mathbf{I} + \mu \mathrm{dev}(\bar{\bm{b}}_e^{tr}) -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 318, 320_ - -**Notation:** -\bm{\sigma}^{tr}: elastic trial Cauchy stress tensor; \mathbf{D}^e: fourth-order elastic stiffness tensor; \Delta \bm{\varepsilon}: total incremental strain tensor; f^{tr}: trial yield function value; \bm{s}^{tr}: trial deviatoric stress tensor; \bm{\alpha}: back-stress tensor for kinematic hardening; \sigma_y: isotropic yield stress; \bar{\varepsilon}^p: equivalent plastic strain; \bm{b}_e: elastic left Cauchy-Green deformation tensor; \bm{f}: relative spatial deformation gradient increment; \bm{\tau}^{tr}: trial Kirchhoff stress tensor; \Psi: hyperelastic strain energy density function; J: determinant of the deformation gradient \mathbf{F}. - - -## 3. Algorithmic Implementation - -**Elastic Trial State Computation Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given total strain increment } \Delta \bm{\varepsilon} \text{ (or relative deformation gradient } \bm{f}\text{) and state variables at } t_n\text{: } \bm{\sigma}^n, \bm{\varepsilon}^p_n, \bm{\alpha}_n, \bar{\varepsilon}^p_n \text{ (or } \bm{b}_e^n\text{)}$ -\If{$\text{Kinematic formulation is infinitesimal small-strain}$} -\State $\bm{\sigma}^{tr} = \bm{\sigma}^n + \mathbf{D}^e : \Delta \bm{\varepsilon}$ -\State $\bm{s}^{tr} = \bm{\sigma}^{tr} - \frac{1}{3} \mathrm{tr}(\bm{\sigma}^{tr}) \mathbf{I}$ -\State $\bm{\eta}^{tr} = \bm{s}^{tr} - \bm{\alpha}_n$ -\State $f^{tr} = \|\bm{\eta}^{tr}\| - \sqrt{\frac{2}{3}} \sigma_y(\bar{\varepsilon}^p_n)$ -\Else -\State $\bm{f} = \mathbf{I} + \frac{\partial \Delta \bm{u}}{\partial \bm{x}_n}$ -\State $\bm{b}_e^{tr} = \bm{f} \cdot \bm{b}_e^n \cdot \bm{f}^T$ -\State $J_{n+1} = \det(\bm{f}) J_n$ -\State $\bar{\bm{b}}_e^{tr} = J_{n+1}^{-2/3} \bm{b}_e^{tr}$ -\State $\bm{\tau}^{tr} = \frac{dU(J_{n+1})}{dJ_{n+1}} J_{n+1} \mathbf{I} + \mu \mathrm{dev}(\bar{\bm{b}}_e^{tr})$ -\State $f^{tr} = \|\mathrm{dev}(\bm{\tau}^{tr})\| - \sqrt{\frac{2}{3}} \sigma_y(\bar{\varepsilon}^p_n)$ -\EndIf -\If{$f^{tr} \le 0$} -\State $\text{Set } \bm{\sigma}^{n+1} = \bm{\sigma}^{tr} \text{ (or } \bm{\tau}^{n+1} = \bm{\tau}^{tr}\text{)}, \bm{\varepsilon}^p_{n+1} = \bm{\varepsilon}^p_n, \bar{\varepsilon}^p_{n+1} = \bar{\varepsilon}^p_n$ -\Return $\text{Step is purely elastic; return trial state as converged state}$ -\Else -\EndIf -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 260, 271, 293-294; Simo_Hughes_1998_Computational inelasticity.pdf Box 3.2, Box 9.1_ - - -## 4. Known Pitfalls - -- **Inappropriate Reference Frame and Stress Measures in Finite-Strain Predictors**: Formulating finite-strain elastic trial states in the reference configuration using the Right Cauchy-Green tensor (C), Second Piola-Kirchhoff stress tensor (S), and Mandel stress tensor (M) fails to preserve spatial objectivity and coaxiality in hyperelasticity-based finite plasticity, which exclusively utilizes the elastic Left Cauchy-Green tensor (b_e) and Kirchhoff stress tensor (\tau). _(Source: Kim_FEA for Elastoplastic Problems.pdf p. 292-294; Simo_Hughes_1998_Computational inelasticity.pdf p. 304, 318-320)_ -- **Drift from Yield Surface in Explicit Predictor-Corrector Integration**: Relying on forward Euler explicit integration or substepping for large load increments causes severe drift from the yield surface and potential instability, whereas unconditionally stable implicit return-mapping (backward Euler) ensures plastic admissibility regardless of step size without needing ad-hoc substepping. _(Source: Dunne_Petrinic_2005_Introduction to computational plasticity.pdf p. 146, 149; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 240-241)_ -- **Misinterpreting Plastic Flow During Elastic Prediction**: Evaluating history-dependent internal variables or plastic flow parameters during the elastic trial calculation introduces spurious plastic dissipation; the elastic predictor step must strictly freeze all plastic internal state variables (\Delta \bm{\varepsilon}^p = \bm{0}, \Delta \bar{\varepsilon}^p = 0). _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 35, 116, 318)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Dunne_Petrinic_2005_Introduction to computational plasticity.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/constit-stress-update-architecture.md b/packages/akms/src/akms/_bundled/global_nodes/constit-stress-update-architecture.md deleted file mode 100644 index d63f0f9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/constit-stress-update-architecture.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -id: constit-stress-update-architecture -title: Stress Update Architecture (Operator Split) -domain: computational-mechanics -subdomain: constitutive -tags: -- constitutive -- stress-update -- return-mapping -- operator-split -- plasticity -status: established -confidence: 0.9 -source: hybrid -edges: -- to: constit-thermodynamic-framework - type: requires - weight: 1.0 -- to: constit-elastic-predictor - type: feeds-into - weight: 1.0 -- to: plasticity-general-return-mapping - type: feeds-into - weight: 1.0 -- to: plasticity-consistent-tangent-general - type: feeds-into - weight: 1.0 -- to: fem-tl-weak-form - type: feeds-into - weight: 0.9 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Stress Update Architecture (Operator Split) - -## Summary - -Stress update architecture uses an operator split to decouple strain-driven elastic prediction from plastic or viscoplastic return-mapping correction. - -## 1. Core Concept - -The stress update architecture in computational inelasticity relies on an operator-split methodology to integrate rate constitutive equations over a discrete time step. The additive operator split decomposes the continuous initial-value problem into two sequential sub-problems: an elastic predictor problem and a plastic or viscoplastic corrector problem. In the elastic predictor phase, plastic deformation and internal variables are frozen, allowing the incremental strain to be processed purely elastically. If the resulting trial stress violates the yield criterion, the corrector phase freezes total strain and executes an implicit return mapping or overstress integration. This projects the stress state back onto the yield surface or relaxes the overstress, updating internal state variables and enabling the exact calculation of an algorithmic consistent tangent operator for global Newton equilibrium iterations. - -## 2. Mathematical Formulation - -**Additive Operator Split of Inelastic Governing Equations** -$$ -\begin{bmatrix} \dot{\bm{\varepsilon}} \\ \dot{\bm{\varepsilon}}^p \\ \dot{\bm{q}} \end{bmatrix} = \begin{bmatrix} \nabla^s \bm{v} \\ \bm{0} \\ \bm{0} \end{bmatrix} + \begin{bmatrix} \bm{0} \\ \dot{\gamma} \frac{\partial f}{\partial \bm{\sigma}} \\ -\dot{\gamma} \bm{h}(\bm{\sigma}, \bm{q}) \end{bmatrix} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 140_ - -**Elastic Predictor Stress and Yield Trial Evaluation** -$$ -\bm{\sigma}^{tr} = \bm{\sigma}^n + \mathbf{D}^e : \Delta \bm{\varepsilon}, \quad \bm{q}^{tr} = \bm{q}_n, \quad f^{tr} = f(\bm{\sigma}^{tr}, \bm{q}_n) -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.5, p. 146; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 240_ - -**Implicit Backward Euler Plastic Corrector Return Mapping** -$$ -\bm{\sigma}_{n+1} = \bm{\sigma}^{tr} - \Delta \gamma \mathbf{D}^e : \left.\frac{\partial f}{\partial \bm{\sigma}}\right|_{n+1}, \quad \bm{q}_{n+1} = \bm{q}_n - \Delta \gamma \bm{h}_{n+1}, \quad f(\bm{\sigma}_{n+1}, \bm{q}_{n+1}) = 0 -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 116, 120; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 242_ - -**Viscoplastic Overstress Evolution Formulations** -$$ -\dot{\bar{\varepsilon}}^{vp} = \frac{1}{\eta} \left\langle \frac{f(\bm{\sigma}, \bm{q})}{\sigma_0} \right\rangle^n \quad \text{or} \quad \dot{\bar{\varepsilon}}^{vp} = \alpha \sinh\left[ \beta (\sigma_e - r - \sigma_y) \right] -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 293, 295; Dunne_Petrinic_2005_Introduction to computational plasticity.pdf p. 41, 180_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; \bm{\sigma}^{tr}: elastic trial Cauchy stress tensor; \mathbf{D}^e: fourth-order elastic stiffness tensor; \bm{\varepsilon}: total strain tensor; \bm{\varepsilon}^p: plastic strain tensor; \bm{\varepsilon}^{vp}: viscoplastic strain tensor; \bm{q}: internal hardening variables vector; f: yield function or flow potential; \gamma, \Delta \gamma: continuous and discrete plastic consistency parameters; \eta: fluidity or viscosity parameter; \sigma_e: equivalent von Mises stress; \sigma_y: static yield stress; r: isotropic hardening stress; \mathbf{D}^{alg}: algorithmic consistent tangent stiffness tensor. - - -## 3. Algorithmic Implementation - -**Operator-Split Stress Update and Return-Mapping Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given converged state at } t_n\text{: } \bm{\sigma}^n, \bm{\varepsilon}^p_n, \bm{q}_n \text{ and strain increment } \Delta \bm{\varepsilon}$ -\State $\bm{\sigma}^{tr} = \bm{\sigma}^n + \mathbf{D}^e : \Delta \bm{\varepsilon}$ -\State $f^{tr} = f(\bm{\sigma}^{tr}, \bm{q}_n)$ -\If{$f^{tr} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{tr}, \quad \bm{\varepsilon}^p_{n+1} = \bm{\varepsilon}^p_n, \quad \bm{q}_{n+1} = \bm{q}_n$ -\Return $\text{Step is purely elastic; return trial state}$ -\Else -\If{$\text{Material model is rate-independent plasticity}$} -\While{$|f(\bm{\sigma}_{n+1}^{(k)}, \bm{q}_{n+1}^{(k)})| > \text{TOL}$} -\State $\text{Solve local Newton-Raphson system for } \Delta \gamma \text{ and return-mapping corrections } \bm{\sigma}_{n+1}, \bm{q}_{n+1}$ -\EndWhile -\ElsIf{$\text{Material model is rate-dependent viscoplasticity}$} -\State $\text{Integrate overstress rate } \dot{\bar{\varepsilon}}^{vp} = \Phi(f) \text{ via backward Euler to solve for } \bm{\sigma}_{n+1}, \bm{\varepsilon}^{vp}_{n+1}, \bm{q}_{n+1}$ -\EndIf -\EndIf -\State $\text{Compute algorithmic consistent tangent tensor } \mathbf{D}^{alg} = \frac{\partial \bm{\sigma}_{n+1}}{\partial \bm{\varepsilon}_{n+1}}$ -\Return $\text{Return updated stress } \bm{\sigma}_{n+1}, \text{ internal variables } \bm{q}_{n+1}, \text{ and consistent tangent tensor } \mathbf{D}^{alg}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.2, p. 124, Box 3.5, p. 146; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 8.1, p. 294_ - - -## 4. Known Pitfalls - -- **Using Continuum Tangent Modulus in Implicit Newton FE Iterations**: Substituting the continuous elastoplastic tangent operator D^{ep} for the algorithmic consistent tangent operator D^{alg} = \partial \bm{\sigma}_{n+1} / \partial \bm{\varepsilon}_{n+1} in implicit finite element solvers destroys the asymptotic quadratic convergence rate of global Newton-Raphson iterations. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 122-124; Kim_FEA for Elastoplastic Problems.pdf p. 236, 248)_ -- **Yield Surface Drift in Explicit Stress Updates**: Integrating constitutive rate equations explicitly without a plastic return-mapping corrector leads to accumulated stress drift off the yield surface and potential numerical divergence, particularly for large load increments. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 240-241; Dunne_Petrinic_2005_Introduction to computational plasticity.pdf p. 146)_ -- **Unphysical Dissipation in Predictor Phase**: Updating internal hardening variables or plastic strains during the elastic predictor phase violates the operator split decomposition, causing spurious energy dissipation before yield admissibility is evaluated. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 140-141)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Dunne_Petrinic_2005_Introduction to computational plasticity.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/constit-thermodynamic-framework.md b/packages/akms/src/akms/_bundled/global_nodes/constit-thermodynamic-framework.md deleted file mode 100644 index 2bcdc1a..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/constit-thermodynamic-framework.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -id: constit-thermodynamic-framework -title: Thermodynamic Framework (Helmholtz, Dissipation) -domain: computational-mechanics -subdomain: constitutive -tags: -- constitutive -- thermodynamics -- internal-variables -- dissipation -- clausius-duhem -status: established -confidence: 0.9 -source: hybrid -edges: -- to: constit-stress-update-architecture - type: feeds-into - weight: 1.0 -- to: plasticity-von-mises - type: feeds-into - weight: 0.9 -- to: damage-continuum-framework - type: feeds-into - weight: 0.8 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Thermodynamic Framework (Helmholtz, Dissipation) - -## Summary - -Thermodynamic framework provides the physical foundation for constitutive modeling, leveraging Helmholtz free energy potentials and the Clausius-Duhem dissipation inequality to enforce thermodynamic consistency. - -## 1. Core Concept - -The thermodynamic framework of constitutive modeling formulates continuum state laws and evolution equations using thermodynamic principles. The internal material state is defined by observable kinematic variables (e.g., elastic strain tensor) and internal state variables representing microstructural evolution, dislocation storage, or damage. The Helmholtz free energy potential determines stress tensors and conjugate thermodynamic forces via the Coleman-Noll procedure. Enforcing the Clausius-Duhem entropy inequality guarantees non-negative mechanical dissipation during inelastic flow. Thermodynamic consistency is established either through the Principle of Maximum Dissipation, which yields associative flow rules and Kuhn-Tucker loading/unloading conditions, or through Onsagerian linear relations coupling thermodynamic forces to flux evolution rates. - -## 2. Mathematical Formulation - -**Helmholtz Free Energy Decomposition and Stress Relation** -$$ -\Psi(\bm{\varepsilon}^e, \bm{\alpha}, a) = \Psi^e(\bm{\varepsilon}^e) + \Psi^k(\bm{\alpha}) + \Psi^i(a), \quad \bm{\sigma} = \frac{\partial \Psi}{\partial \bm{\varepsilon}^e} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 27, 104; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf p. 5390_ - -**Clausius-Duhem Dissipation Inequality** -$$ -\mathcal{D}_{mech} = \bm{\sigma} : \dot{\bm{\varepsilon}}^p + \bm{A} : \dot{\bm{\alpha}} + A_a \dot{a} \ge 0, \quad \bm{A} = -\frac{\partial \Psi}{\partial \bm{\alpha}}, \quad A_a = -\frac{\partial \Psi}{\partial a} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 27, 101; entropy-25-00721-v2.pdf p. 9, 10_ - -**Principle of Maximum Plastic Dissipation** -$$ -(\bm{\sigma} - \bm{\tau}^*) : \dot{\bm{\varepsilon}}^p + (\bm{A} - \bm{A}^*) : \dot{\bm{\alpha}} \ge 0 \quad \forall (\bm{\tau}^*, \bm{A}^*) \in \mathbb{E}_{\sigma} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 98-102; Kim_FEA for Elastoplastic Problems.pdf p. 296-298_ - -**Onsagerian Thermodynamic Linear Flux-Force Relations** -$$ -\begin{bmatrix} \dot{\bm{\alpha}} \\ \bm{q} \end{bmatrix} = \mathbf{M} \begin{bmatrix} -\frac{\partial \Psi}{\partial \bm{\alpha}} \\ -\nabla \theta \end{bmatrix} -$$ -_Source: entropy-25-00721-v2.pdf p. 8, 10, 12_ - -**Notation:** -\Psi: Helmholtz free energy density per unit reference volume; \bm{\varepsilon}^e: elastic strain tensor; \bm{\varepsilon}^p: plastic strain tensor; \bm{\sigma}: Cauchy stress tensor; \bm{\alpha}: kinematic hardening back-stress tensor internal variable; a: isotropic hardening scalar internal variable; \bm{A}: thermodynamic force conjugate to \bm{\alpha}; A_a: thermodynamic force conjugate to a; \mathcal{D}_{mech}: mechanical rate of energy dissipation per unit volume; \mathbb{E}_{\sigma}: closed convex elastic domain in stress/force space; f: yield function; \mathbf{M}: positive semi-definite Onsagerian response matrix; \theta: absolute temperature; \bm{q}: heat flux vector. - - -## 3. Algorithmic Implementation - -**Thermodynamic State Determination and Dissipation Verification** -$$ -\begin{algorithmic} -\State $\text{Given total strain } \bm{\varepsilon}_{n+1}, \text{ internal state } \bm{\alpha}_n, a_n, \text{ and free energy function } \Psi(\bm{\varepsilon}^e, \bm{\alpha}, a)$ -\State $\text{Compute trial elastic strain } \bm{\varepsilon}^{e,tr} = \bm{\varepsilon}_{n+1} - \bm{\varepsilon}^p_n \text{ and trial stress } \bm{\sigma}^{tr} = \left.\frac{\partial \Psi}{\partial \bm{\varepsilon}^e}\right|^{tr}$ -\State $\text{Compute thermodynamic conjugate forces } \bm{A}_n = -\frac{\partial \Psi}{\partial \bm{\alpha}_n}, \quad A_{a,n} = -\frac{\partial \Psi}{\partial a_n}$ -\State $f^{tr} = f(\bm{\sigma}^{tr}, \bm{A}_n, A_{a,n})$ -\If{$f^{tr} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{tr}, \quad \bm{\alpha}_{n+1} = \bm{\alpha}_n, \quad a_{n+1} = a_n, \quad \mathcal{D}_{mech} = 0$ -\Return $\text{Process is purely elastic; dissipation is zero and state is accepted}$ -\Else -\EndIf -\State $\dot{\bm{\varepsilon}}^p = \dot{\gamma} \frac{\partial f}{\partial \bm{\sigma}}, \quad \dot{\bm{\alpha}} = \dot{\gamma} \frac{\partial f}{\partial \bm{A}}, \quad \dot{a} = \dot{\gamma} \frac{\partial f}{\partial A_a}$ -\State $\mathcal{D}_{mech} = \bm{\sigma}_{n+1} : \dot{\bm{\varepsilon}}^p + \bm{A}_{n+1} : \dot{\bm{\alpha}} + A_{a,n+1} \dot{a} = \dot{\gamma} \left(\bm{\sigma}_{n+1} : \frac{\partial f}{\partial \bm{\sigma}} + \bm{A}_{n+1} : \frac{\partial f}{\partial \bm{A}} + A_{a,n+1} \frac{\partial f}{\partial A_a}\right)$ -\If{$\mathcal{D}_{mech} \ge 0$} -\State $\text{Update state variables } \bm{\sigma}_{n+1}, \bm{\varepsilon}^p_{n+1}, \bm{\alpha}_{n+1}, a_{n+1}$ -\Return $\text{Thermodynamic consistency verified; accept state}$ -\Else -\EndIf -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 27-28, 98-102; Kim_FEA for Elastoplastic Problems.pdf p. 296-298; entropy-25-00721-v2.pdf p. 8-10_ - - -## 4. Known Pitfalls - -- **Assuming Unconstrained State Variable Independence in Internal Variable Theories**: Applying Coleman-Noll procedures directly to internal variables assumes their time rates can be controlled independently on boundaries; however, internal variables are observable but not controllable, requiring Onsagerian linear flux-force relations or thermodynamic variational principles (Principle of Maximum Dissipation) to establish evolution equations. _(Source: entropy-25-00721-v2.pdf p. 2, 8; Simo_Hughes_1998_Computational inelasticity.pdf p. 98-102)_ -- **Ignoring Stored Energy of Hardening in Heat Generation Calculations**: Assuming all plastic work is converted into thermal dissipation ignores the thermodynamic energy storage in dislocation microstructures (\Psi^k, \Psi^i), overestimating the Taylor-Quinney coefficient and thermal softening in coupled thermomechanical problems. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 27-28; Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 4, 10)_ -- **Spurious Dissipation in Elastic Predictor Step**: Evolving internal state variables or plastic strains during the elastic trial evaluation violates the Coleman-Noll thermoelastic constitutive relation, generating unphysical mechanical dissipation before yield admissibility is determined. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 27, 103-104; Kim_FEA for Elastoplastic Problems.pdf p. 296-298)_ - -## References - -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- entropy-25-00721-v2.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-bai-wierzbicki.md b/packages/akms/src/akms/_bundled/global_nodes/damage-bai-wierzbicki.md deleted file mode 100644 index 8654719..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-bai-wierzbicki.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: damage-bai-wierzbicki -title: Bai-Wierzbicki / MMC Fracture Model -domain: computational-mechanics -subdomain: damage -tags: -- damage -- bai-wierzbicki -- mmc -- lode-angle -- ductile-fracture -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-lode-triaxiality - type: requires - weight: 1.0 -- to: damage-johnson-cook-failure - type: refines - weight: 0.9 -- to: damage-continuum-framework - type: refines - weight: 0.8 -- to: damage-element-erosion - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Bai-Wierzbicki / MMC Fracture Model - -## Summary - -Bai-Wierzbicki / MMC fracture model formulates a stress-state-dependent ductile failure locus using stress triaxiality and the Lode parameter. - -## 1. Core Concept - -The Bai-Wierzbicki / Modified Mohr-Coulomb (MMC) ductile fracture model extends classical failure criteria by explicitly incorporating both stress triaxiality and the Lode parameter. Ductile fracture strain is expressed as a multi-variable surface in stress-state space, capturing asymmetric material ductility under tension, shear, and compression loading paths. Phenomenological damage accumulation integrates incremental plastic strain normalized by the instantaneous fracture strain threshold. This formulation accounts for localized shear band failure and the characteristic cusp observed in plane-stress fracture loci. - -## 2. Mathematical Formulation - -**Stress Triaxiality and Lode Parameter Definitions** -$$ -T = \frac{\sigma_m}{\sigma_{eq}}, \quad L = \frac{27 J_3}{2 \sigma_{eq}^3} = \frac{2 \sigma_2 - \sigma_1 - \sigma_3}{\sigma_1 - \sigma_3} -$$ -_Source: Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 609; Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 536_ - -**Plane-Stress Triaxiality-Lode Interdependence** -$$ -T(\rho) = \frac{\operatorname{sgn}(\sigma_1)(\rho + 1)}{3 \sqrt{\rho^2 - \rho + 1}}, \quad L(\rho) = \frac{(1 + \rho)(2 - \rho)(2\rho - 1)}{2 (\rho^2 - \rho + 1)^{3/2}} -$$ -_Source: Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 612; Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 536, 552_ - -**Stress-State-Dependent Fracture Strain Surface** -$$ -\bar{\varepsilon}_f = \bar{\varepsilon}_f(T, L) -$$ -_Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 444; Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 585, 622_ - -**Phenomenological Damage Accumulation Rule** -$$ -D = \int_0^{\bar{\varepsilon}^p} \frac{d\bar{\varepsilon}^p}{\bar{\varepsilon}_f(T, L)} \ge 1 -$$ -_Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 444; Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 536, 558_ - -**Notation:** -T: stress triaxiality ratio; L: normalized Lode parameter; \sigma_m: hydrostatic stress; \sigma_{eq}: von Mises equivalent stress; \bm{s}: deviatoric stress tensor; J_3: third invariant of deviatoric stress; \sigma_1, \sigma_2, \sigma_3: principal stress values; \rho: principal stress ratio under plane stress; \bar{\varepsilon}^p: equivalent plastic strain; \bar{\varepsilon}_f: fracture strain threshold; D: scalar damage accumulation parameter. - - -## 3. Algorithmic Implementation - -**Bai-Wierzbicki / MMC Fracture State Update Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given stress tensor } \bm{\sigma}_{n+1}, \text{ equivalent plastic strain increment } \Delta \bar{\varepsilon}^p, \text{ and previous damage } D_n$ -\State $\sigma_m = \frac{1}{3} \mathrm{tr}(\bm{\sigma}_{n+1}), \quad \bm{s} = \bm{\sigma}_{n+1} - \sigma_m \mathbf{I}, \quad \sigma_{eq} = \sqrt{\frac{3}{2} \bm{s}:\bm{s}}$ -\State $T = \frac{\sigma_m}{\sigma_{eq}}, \quad J_3 = \det(\bm{s}), \quad L = \frac{27 J_3}{2 \sigma_{eq}^3}$ -\State $\bar{\varepsilon}_f = \bar{\varepsilon}_f(T, L)$ -\State $\Delta D = \frac{\Delta \bar{\varepsilon}^p}{\bar{\varepsilon}_f(T, L)}, \quad D_{n+1} = D_n + \Delta D$ -\If{$D_{n+1} \ge 1.0$} -\State $\text{Material point reaches fracture initiation threshold}$ -\Return $\text{Initiate element erosion or stress degradation } (D_{n+1} = 1.0)$ -\Else -\EndIf -\Return $\text{Return updated damage state } D_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 444; Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 536, 558_ - - -## 4. Known Pitfalls - -- **Neglecting Lode Parameter Dependence in Low-Triaxiality Shear Loading**: Relying exclusively on stress triaxiality T without Lode parameter L dependence overpredicts ductility under shear-dominated loadings (L \approx 0), failing to capture the characteristic ductility drop and cusp observed in plane-stress fracture loci. _(Source: Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 585, 621-622; Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 536, 552-553)_ -- **Unphysical Stress Extrapolation in Uncoupled Damage Accumulation**: Integrating phenomenological damage uncoupled from elastoplastic constitutive equations without stress degradation allows stress to increase due to plastic hardening even as damage approaches unity, predicting unphysical energy dissipation during final material failure. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 470-471; Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 564-565)_ -- **Non-Proportional Loading Path Miscalibration**: Applying fracture loci calibrated strictly under proportional loading paths (constant T and L) to complex non-proportional histories introduces errors, as strain path changes alter void distortion and localized band formation. _(Source: Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 558, 567)_ - -## References - -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf -- Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf -- Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-cockcroft-latham.md b/packages/akms/src/akms/_bundled/global_nodes/damage-cockcroft-latham.md deleted file mode 100644 index 09151e1..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-cockcroft-latham.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: damage-cockcroft-latham -title: Cockcroft-Latham Fracture Criterion -domain: computational-mechanics -subdomain: damage -tags: -- damage -- cockcroft-latham -- principal-stress -- ductile-fracture -- simple-criterion -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-continuum-framework - type: refines - weight: 0.7 -- to: damage-johnson-cook-failure - type: contradicts - weight: 0.6 -- to: tensor-spectral-decomposition - type: requires - weight: 0.7 -context_size: small -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Cockcroft-Latham Fracture Criterion - -## Summary - -Principal stress-based ductile fracture models evaluate material degradation and failure initiation driven by the maximum tensile principal stress and plastic strain accumulation. - -## 1. Core Concept - -Principal stress-based ductile failure criteria postulate that tensile failure and scalar damage growth are primarily driven by the maximum principal tensile stress. In continuum damage mechanics and computational plasticity, tensor spectral decomposition extracts the maximum principal stress component, where a Heaviside step function or Macaulay bracket isolates tensile stress states from compressive states. Damage accumulation evolves as a function of the ratio of maximum principal stress to equivalent stress scaled by effective plastic strain rates, or via Rankine-type limit surfaces where the maximum principal stress reaches the material tensile strength. - -## 2. Mathematical Formulation - -**Maximum Principal Stress Scalar Damage Evolution Rate** -$$ -\dot{\omega} = \left(\frac{\sigma_1}{\sigma_e}\right)^\chi H(\sigma_1) \dot{\bar{\varepsilon}}^p -$$ -_Source: Dunne_Petrinic_2005_Introduction to computational plasticity.pdf p. 211_ - -**Rankine Maximum Principal Stress Failure Criterion** -$$ -f(\bm{\sigma}) = \sigma_1 - f_t = 0 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 201, 226, 254_ - -**Spectral Decomposition of Cauchy Stress Tensor** -$$ -\bm{\sigma} = \sum_{i=1}^3 \sigma_i \bm{n}_i \otimes \bm{n}_i -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 368; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 266_ - -**Plane-Stress Principal Stress Ratio and Triaxiality** -$$ -\rho = \frac{\sigma_2}{\sigma_1}, \quad T = \frac{\operatorname{sgn}(\sigma_1)(\rho + 1)}{3 \sqrt{\rho^2 - \rho + 1}} -$$ -_Source: Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 612; Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 536_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; \sigma_1: maximum principal Cauchy stress; \sigma_e: von Mises equivalent stress; \bm{s}: deviatoric stress tensor; H(\cdot): Heaviside step function; \omega: scalar damage variable; \chi: stress-state sensitivity parameter; \bar{\varepsilon}^p: equivalent plastic strain; f_t: uniaxial tensile strength; \bm{n}_i: principal stress eigenvectors; \rho: principal stress ratio; T: stress triaxiality. - - -## 3. Algorithmic Implementation - -**Maximum Principal Stress Damage State Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given stress tensor } \bm{\sigma}_{n+1}, \text{ equivalent plastic strain increment } \Delta \bar{\varepsilon}^p, \text{ and previous damage } \omega_n$ -\State $\text{Compute principal stress eigenvalues } \sigma_1 \ge \sigma_2 \ge \sigma_3 \text{ via spectral decomposition of } \bm{\sigma}_{n+1}$ -\State $\sigma_e = \sqrt{\frac{3}{2} \bm{s}:\bm{s}}, \quad \text{where } \bm{s} = \bm{\sigma}_{n+1} - \frac{1}{3}\mathrm{tr}(\bm{\sigma}_{n+1})\mathbf{I}$ -\If{$\sigma_1 > 0$} -\State $\Delta \omega = \left(\frac{\sigma_1}{\sigma_e}\right)^\chi \Delta \bar{\varepsilon}^p$ -\Else -\EndIf -\State $\omega_{n+1} = \omega_n + \Delta \omega$ -\If{$\omega_{n+1} \ge 1.0 \text{ or } \sigma_1 \ge f_t$} -\State $\text{Material point reaches tensile fracture initiation threshold}$ -\Return $\text{Set failure state } \omega_{n+1} = 1.0 \text{ and degrade stress}$ -\Else -\EndIf -\Return $\text{Return updated damage state } \omega_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Dunne_Petrinic_2005_Introduction to computational plasticity.pdf p. 211; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 201, 266_ - - -## 4. Known Pitfalls - -- **Spurious Damage Growth Under Compressive Principal Stresses**: Failing to apply a Heaviside step function H(\sigma_1) or spectral positive stress projection to isolate the maximum principal tensile stress leads to unphysical damage accumulation during purely compressive stress states. _(Source: Dunne_Petrinic_2005_Introduction to computational plasticity.pdf p. 211; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 444)_ -- **Neglecting Triaxiality and Lode Effects in Shear Loading**: Relying solely on maximum principal stress or Rankine failure criteria without accounting for stress triaxiality T or Lode parameter L underpredicts shear localization and fails to capture ductility minima in plane stress. _(Source: Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 536, 552; Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 585, 622)_ -- **Indeterminacy in Eigenvector Derivatives for Coincident Principal Stresses**: Evaluating derivatives of principal stress functions when two principal stresses coincide (\sigma_1 = \sigma_2) causes numerical indeterminacy during return-mapping or tangent operator evaluation, requiring specialized eigenprojection formulas. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 261-266; Kim_FEA for Elastoplastic Problems.pdf p. 374-375)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Dunne_Petrinic_2005_Introduction to computational plasticity.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf -- Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-continuum-framework.md b/packages/akms/src/akms/_bundled/global_nodes/damage-continuum-framework.md deleted file mode 100644 index ba0f9f1..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-continuum-framework.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: damage-continuum-framework -title: Continuum Damage Mechanics Framework -domain: computational-mechanics -subdomain: damage -tags: -- damage -- cdm -- lemaitre -- kachanov -- effective-stress -status: established -confidence: 0.9 -source: hybrid -edges: -- to: constit-thermodynamic-framework - type: requires - weight: 1.0 -- to: plasticity-von-mises - type: feeds-into - weight: 0.9 -- to: damage-johnson-cook-failure - type: feeds-into - weight: 0.8 -- to: damage-bai-wierzbicki - type: feeds-into - weight: 0.8 -- to: damage-gtn-yield-function - type: feeds-into - weight: 0.8 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Continuum Damage Mechanics Framework - -## Summary - -Continuum damage mechanics models material degradation through internal variables that reduce the effective load-carrying area and degrade secant elastic stiffness. - -## 1. Core Concept - -The Continuum Damage Mechanics (CDM) framework describes the progressive degradation of material stiffness and strength caused by microstructural micro-cracks and void growth. A scalar or tensor-valued damage variable \omega \in [1] quantifies the reduction in load-carrying area, establishing the effective stress concept \hat{\bm{\sigma}} = \bm{\sigma} / (1 - \omega). Under isotropic elasticity-based damage, the secant stiffness degrades as \mathbf{D}^s = (1 - \omega) \mathbf{D}^e, relating Cauchy stress to total or elastic strain. Damage evolution is driven by an equivalent strain measure \tilde{\varepsilon} and enforced via Karush-Kuhn-Tucker loading/unloading conditions against a history threshold \kappa. When combined with computational plasticity, effective stresses enter the yield criterion and flow rule, while damage accumulation induces material strain softening. - -## 2. Mathematical Formulation - -**Effective Stress and Isotropic Secant Stiffness Relation** -$$ -\bm{\sigma} = (1 - \omega) \hat{\bm{\sigma}}, \quad \hat{\bm{\sigma}} = \mathbf{D}^e : \bm{\varepsilon} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 171-172_ - -**Damage Loading Function and KKT Conditions** -$$ -f(\tilde{\varepsilon}, \kappa) = \tilde{\varepsilon} - \kappa \le 0, \quad \dot{\kappa} \ge 0, \quad f \dot{\kappa} = 0 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 172_ - -**Energy-Based Equivalent Strain Definition** -$$ -\tilde{\varepsilon} = \frac{1}{2} \bm{\varepsilon} : \mathbf{D}^e : \bm{\varepsilon} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 172_ - -**Coupled Elasticity-Damage-Plasticity Constitutive Relation** -$$ -\bm{\sigma} = (1 - \omega) \mathbf{D}^e : \bm{\varepsilon}^e, \quad f^p(\hat{\bm{\sigma}}, \kappa^p) \le 0 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 270; Simo_Hughes_1998_Computational inelasticity.pdf p. 140_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; \hat{\bm{\sigma}}: effective stress tensor; \omega: scalar damage parameter (0 \le \omega \le 1); \mathbf{D}^e: fourth-order elastic stiffness tensor; \mathbf{D}^s: degraded secant stiffness tensor; \bm{\varepsilon}: total strain tensor; \bm{\varepsilon}^e: elastic strain tensor; \bm{\varepsilon}^p: plastic strain tensor; \tilde{\varepsilon}: equivalent strain measure; \kappa: internal damage history parameter; f: damage loading function; f^p: plastic yield function. - - -## 3. Algorithmic Implementation - -**Isotropic Elasticity-Based Damage Update Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given strain increment } \Delta \bm{\varepsilon}_{j+1}, \text{ previous total strain } \bm{\varepsilon}_0, \text{ and previous damage history } \kappa_0$ -\State $\bm{\varepsilon}_{j+1} = \bm{\varepsilon}_0 + \Delta \bm{\varepsilon}_{j+1}$ -\State $\tilde{\varepsilon}_{j+1} = \tilde{\varepsilon}(\bm{\varepsilon}_{j+1})$ -\State $f = \tilde{\varepsilon}_{j+1} - \kappa_0$ -\If{$f \ge 0$} -\State $\kappa_{j+1} = \tilde{\varepsilon}_{j+1}$ -\Else -\EndIf -\State $\omega_{j+1} = \omega(\kappa_{j+1})$ -\State $\hat{\bm{\sigma}}_{j+1} = \mathbf{D}^e : \bm{\varepsilon}_{j+1}$ -\State $\bm{\sigma}_{j+1} = (1 - \omega_{j+1}) \hat{\bm{\sigma}}_{j+1}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{j+1} \text{ and history } \kappa_{j+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 6.1, p. 174_ - - -## 4. Known Pitfalls - -- **Mesh Sensitivity and Loss of Ellipticity Under Local Strain Softening**: Incorporating strain-softening damage into local rate-independent continuum models causes the governing partial differential equations to lose ellipticity, leading to pathological mesh sensitivity where energy dissipation vanishes as the finite element size approaches zero. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 179-184; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 477-478)_ -- **Spurious Energy Dissipation Near Complete Damage Singularity**: Evaluating plastic strain rates or stress updates without proper numerical bounds as damage approaches complete failure (\omega \to 1) creates severe numerical ill-conditioning or unphysical stress growth if damage is uncoupled from plastic hardening. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 470-471; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 182-184)_ -- **Ignoring Asymmetric Damage in Tension versus Compression**: Applying isotropic damage degradation equally to compressive and tensile stress states causes unphysical degradation under hydrostatic compression, failing to reflect crack closure effects (unilateral contact). _(Source: Meng and Tabiei - 2024 - Phase field modeling of ductile fracture with isotropic hardening and radius return method.pdf p. 417-418; Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 470-471)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Dunne_Petrinic_2005_Introduction to computational plasticity.pdf -- Meng and Tabiei - 2024 - Phase field modeling of ductile fracture with isotropic hardening and radius return method.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-element-erosion.md b/packages/akms/src/akms/_bundled/global_nodes/damage-element-erosion.md deleted file mode 100644 index 0985e09..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-element-erosion.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -id: damage-element-erosion -title: Element Erosion & Deletion Techniques -domain: computational-mechanics -subdomain: damage -tags: -- damage -- element-erosion -- explicit-dynamics -- mass-conservation -- particle-conversion -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-continuum-framework - type: requires - weight: 0.9 -- to: damage-johnson-cook-failure - type: requires - weight: 0.9 -- to: damage-bai-wierzbicki - type: requires - weight: 0.9 -- to: damage-spall - type: feeds-into - weight: 0.9 -- to: fem-assembly-algorithm - type: feeds-into - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Element Erosion & Deletion Techniques - -## Summary - -Element erosion and failure modeling in explicit dynamic finite element analysis represent material failure through smeared continuum damage degradation or discrete element disconnection. - -## 1. Core Concept - -In explicit dynamic finite element modeling, material failure and element degradation are represented either through discrete crack disconnections that modify mesh topology or smeared continuum damage formulations that scale stress and stiffness tensors by degradation functions. In explicit solvers such as LS-DYNA and Abaqus/Explicit, multi-point solid elements require integration-point damage averaging across Gauss points to prevent stress equilibrium instabilities. Furthermore, to avoid numerical singularities as damage approaches unity or porosity reaches coalescence limits, damage or void volume fraction variables are numerically capped at a threshold (e.g., 90% of the failure limit) to maintain solver stability during dynamic impact and spallation simulations. - -## 2. Mathematical Formulation - -**Smeared Damage Stress Degradation Relation** -$$ -\bm{\sigma} = g(d) \bm{\sigma}^+ + \bm{\sigma}^-, \quad g(d) = (1 - d)^2 -$$ -_Source: Meng and Tabiei - 2024 - Phase field modeling of ductile fracture with isotropic hardening and radius return method.pdf p. 10; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 10_ - -**Integration-Point Averaged Damage Variable for Element Stiffness** -$$ -\bar{d}_e = \frac{1}{n_{gp}} \sum_{i=1}^{n_{gp}} d_i -$$ -_Source: Meng and Tabiei - 2024 - Phase field modeling of ductile fracture with isotropic hardening and radius return method.pdf p. 15_ - -**Numerical Porosity Threshold Capping for Solver Stability** -$$ -f_{nodal} = \min\left(f, 0.9 f_r\right) -$$ -_Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 6_ - -**Discrete Interface Traction Failure Threshold** -$$ -t_n \ge f_t \implies \text{Create new nodal DOFs across } S_d -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 201_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; d: scalar damage or phase-field variable (0 \le d \le 1); g(d): continuous material degradation function; \bm{\sigma}^+, \bm{\sigma}^-: positive (tensile) and negative (compressive) stress tensor components; \bar{d}_e: element-averaged damage variable; n_{gp}: number of element Gauss integration points; f: void volume fraction (porosity); f_r: critical porosity failure limit; t_n: normal interface traction vector; f_t: material tensile strength threshold; S_d: element boundary failure surface. - - -## 3. Algorithmic Implementation - -**Explicit Dynamic Damage Degradation and Element Removal Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given element strain increment } \Delta \bm{\varepsilon}_{n+1}, \text{ previous state variables at } t_n, \text{ and explicit time step } \Delta t$ -\For{$\text{Each Gauss integration point } i = 1, \dots, n_{gp} \text{ in element } e$} -\State $\text{Compute local strain } \bm{\varepsilon}_i^{n+1} = \bm{\varepsilon}_i^n + \Delta \bm{\varepsilon}_i \text{ and trial stress } \bm{\sigma}_i^{tr}$ -\State $\text{Evaluate plastic yield and void/damage evolution } \dot{f}_i \text{ or } \dot{d}_i$ -\State $d_i^{n+1} = d_i^n + \dot{d}_i \Delta t$ -\EndFor -\State $\text{Compute element-averaged damage: } \bar{d}_e = \frac{1}{n_{gp}} \sum_{i=1}^{n_{gp}} d_i^{n+1}$ -\If{$\bar{d}_e \ge d_{thresh} \quad (d_{thresh} \approx 0.90 \text{ or } 0.9 f_r)$} -\State $\text{Cap damage/porosity at threshold to prevent numerical ill-conditioning: } \bar{d}_e = d_{thresh}$ -\State $\text{Degrade elastic moduli and yield stress: } E_{degraded} = g(\bar{d}_e) E_0, \quad \sigma_{y,degraded} = g(\bar{d}_e) \sigma_{y0}$ -\Else -\EndIf -\State $\bm{\sigma}_e^{n+1} = g(\bar{d}_e) \bm{\sigma}_e^+ + \bm{\sigma}_e^-$ -\State $\text{Assemble element internal force vector: } \bm{f}_{int}^e = \int_{V_e} \mathbf{B}^T \bm{\sigma}_e^{n+1} dV$ -\Return $\text{Return degraded element stress } \bm{\sigma}_e^{n+1} \text{ and internal force vector } \bm{f}_{int}^e$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Meng and Tabiei - 2024 - Phase field modeling of ductile fracture with isotropic hardening and radius return method.pdf p. 10, 15; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 6; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 174_ - - -## 4. Known Pitfalls - -- **Unstable Stress Equilibrium from Independent Integration Point Degradation**: Degrading material stiffness independently at individual Gauss integration points in multi-point solid elements (e.g., 8-node 3D hexahedra) causes spatial stress oscillations and numerical instability in explicit time integration; averaging damage across all Gauss points stabilizes the element formulation. _(Source: Meng and Tabiei - 2024 - Phase field modeling of ductile fracture with isotropic hardening and radius return method.pdf p. 15)_ -- **Numerical Singularity and Solver Failure Near Complete Failure**: Allowing damage or void volume fraction to reach complete material failure (\omega \to 1 or f \to f_r) causes division by zero and matrix ill-conditioning; capping porosity or damage at a threshold (e.g., 90% of the failure limit) preserves numerical robustness during explicit shock and impact simulations. _(Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 6; Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 470-471)_ -- **Mesh Alignment Sensitivity in Discrete Element Disconnection**: Deleting elements or disconnecting nodes along pre-existing element boundaries forces crack propagation paths to follow the finite element mesh orientation, introducing severe mesh alignment bias unless enriched partition-of-unity or smeared gradient regularization techniques are applied. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 179-182, 201; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 404)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Meng and Tabiei - 2024 - Phase field modeling of ductile fracture with isotropic hardening and radius return method.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-consistent-tangent.md b/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-consistent-tangent.md deleted file mode 100644 index 518dcae..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-consistent-tangent.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: damage-gtn-consistent-tangent -title: GTN Consistent Algorithmic Tangent -domain: computational-mechanics -subdomain: damage -tags: -- damage -- gtn -- consistent-tangent -- aravas -- newton -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-gtn-return-mapping - type: requires - weight: 1.0 -- to: damage-gtn-yield-function - type: requires - weight: 0.9 -- to: plasticity-consistent-tangent-general - type: refines - weight: 0.9 -- to: fem-newton-raphson - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# GTN Consistent Algorithmic Tangent - -## Summary - -GTN consistent algorithmic tangent derives from the exact linearization of the implicit return-mapping algorithm, providing closed-form algorithmic moduli for Newton-Raphson iterations. - -## 1. Core Concept - -The consistent algorithmic tangent tensor for the Gurson-Tvergaard-Needleman (GTN) porous plasticity model is obtained by exact linearization of the discrete implicit backward Euler return-mapping state update. Unlike the continuum elastoplastic tangent operator, which is derived from continuous rate equations, the algorithmic tangent accounts for the discrete step size and non-linear void evolution. As shown by Zhang (1995) following Aravas (1987), the GTN consistent tangent tensor can be expressed in an explicit, closed-form 4th-order structure involving five scalar coefficients without requiring 4th-order matrix inversions. Utilizing the consistent tangent operator in global implicit finite element solvers preserves the asymptotic quadratic convergence rate of Newton-Raphson iterations. - -## 2. Mathematical Formulation - -**Explicit 4th-Order Consistent Algorithmic Tangent Structure** -$$ -\mathbf{D}^{consis} = d_0 \mathbf{J} + d_1 \mathbf{I} \otimes \mathbf{I} + d_2 \mathbf{n} \otimes \mathbf{n} + d_3 \mathbf{n} \otimes \mathbf{I} + d_4 \mathbf{I} \otimes \mathbf{n} -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 35_ - -**Closed-Form GTN Tangent Coefficients** -$$ -d_0 = 2G \frac{q}{q^{tr}}, \quad d_1 = K - \frac{2G}{3}\frac{q}{q^{tr}} - 3K^2 C_{11}, \quad d_2 = \frac{4G^2}{q^{tr}} \Delta \varepsilon_q - 4G^2 C_{22}, \quad d_3 = -2GK C_{12}, \quad d_4 = -6GK C_{21} -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 35_ - -**Linearized Flow and Yield Condition Matrix System** -$$ -\begin{bmatrix} A_{11} & A_{12} \\ A_{21} & A_{22} \end{bmatrix} \begin{bmatrix} \partial \Delta \varepsilon_p \\ \partial \Delta \varepsilon_q \end{bmatrix} = \begin{bmatrix} B_{11} \mathbf{I} + B_{12} \mathbf{n} \\ B_{21} \mathbf{I} + B_{22} \mathbf{n} \end{bmatrix} : \partial \bm{\sigma} -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 34-35, 41-43_ - -**GTN Tangent Major Symmetry Condition** -$$ -d_3 = d_4 \iff C_{12} = 3 C_{21} -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 35_ - -**Notation:** -\mathbf{D}^{consis}: fourth-order consistent algorithmic tangent stiffness tensor; \mathbf{J}: fourth-order symmetric identity tensor; \mathbf{I}: second-order identity tensor; \mathbf{n}: unit deviatoric normal tensor; d_0, d_1, d_2, d_3, d_4: scalar GTN tangent coefficients; G: elastic shear modulus; K: elastic bulk modulus; q: updated equivalent von Mises stress; q^{tr}: trial equivalent von Mises stress; \Delta \varepsilon_p: hydrostatic plastic strain increment; \Delta \varepsilon_q: equivalent plastic strain increment; A_{ij}, B_{ij}, C_{ij}: scalar linearization coefficients. - - -## 3. Algorithmic Implementation - -**GTN Algorithmic Consistent Tangent Evaluation Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given converged state at } t_{n+1}\text{: stress } \bm{\sigma}_{n+1}, \text{ trial stress } q^{tr}, \text{ plastic strain increments } \Delta \varepsilon_p, \Delta \varepsilon_q, \text{ and unit normal } \mathbf{n} = \frac{3}{2q}\bm{s}_{n+1}$ -\State $\text{Compute partial derivatives of GTN yield function } \Phi(\sigma_m, q, f) \text{ and matrix hardening } H(\bar{\varepsilon}^p)$ -\State $\text{Evaluate Aravas system matrices } A_{ij} \text{ and } B_{ij}$ -\State $\text{Invert } 2 \times 2 \text{ matrix } \mathbf{A}\text{: } \mathbf{C} = \mathbf{A}^{-1} \mathbf{B}$ -\State $d_0 = 2G \frac{q}{q^{tr}}$ -\State $d_1 = K - \frac{2G}{3}\frac{q}{q^{tr}} - 3K^2 C_{11}$ -\State $d_2 = \frac{4G^2}{q^{tr}} \Delta \varepsilon_q - 4G^2 C_{22}$ -\State $d_3 = -2GK C_{12}, \quad d_4 = -6GK C_{21}$ -\State $\mathbf{D}^{consis} = d_0 \mathbf{J} + d_1 \mathbf{I} \otimes \mathbf{I} + d_2 \mathbf{n} \otimes \mathbf{n} + d_3 \mathbf{n} \otimes \mathbf{I} + d_4 \mathbf{I} \otimes \mathbf{n}$ -\Return $\text{Return explicit 4th-order consistent tangent tensor } \mathbf{D}^{consis}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 34-35_ - - -## 4. Known Pitfalls - -- **Loss of Quadratic Convergence with Continuum Tangent Operator**: Using the continuum elastoplastic tangent operator D^{ep} in implicit global Newton-Raphson solvers instead of the algorithmic consistent tangent operator D^{consis} degrades convergence from quadratic to linear, requiring significantly more iterations per load step. _(Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 31, 38; Kim_FEA for Elastoplastic Problems.pdf p. 243, 252)_ -- **Spurious Non-Symmetry from Index Misalignment**: Assuming minor or major symmetry of D^{consis} when C_12 \neq 3 C_21 introduces errors in symmetric global FE solvers; major symmetry holds if and only if C_12 = 3 C_21, which requires careful coefficient calculation. _(Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 35)_ -- **Division by Zero at Zero Trial Deviatoric Stress**: Evaluating d_0, d_2, or n = 3s / (2q) as trial deviatoric stress approaches zero (q^{tr} \to 0) causes floating-point division by zero; hydrostatic or purely elastic states must revert to the isotropic elastic tangent tensor D^e. _(Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 34-35; Kim_FEA for Elastoplastic Problems.pdf p. 252-254)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-return-mapping.md b/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-return-mapping.md deleted file mode 100644 index 00d3063..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-return-mapping.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -id: damage-gtn-return-mapping -title: Return Mapping for GTN -domain: computational-mechanics -subdomain: damage -tags: -- damage -- gtn -- return-mapping -- aravas -- implicit-integration -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-gtn-yield-function - type: requires - weight: 1.0 -- to: damage-gtn-void-evolution - type: requires - weight: 1.0 -- to: plasticity-general-return-mapping - type: refines - weight: 0.9 -- to: damage-gtn-consistent-tangent - type: feeds-into - weight: 1.0 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Return Mapping for GTN - -## Summary - -Implicit return mapping for the GTN porous plasticity model decouples stress updates into hydrostatic and deviatoric scalar equations solved via a two-variable Newton-Raphson scheme. - -## 1. Core Concept - -The return-mapping algorithm for the Gurson-Tvergaard-Needleman (GTN) model integrates pressure-dependent porous plastic constitutive equations over discrete time steps. Following the operator split, the elastic trial stress is computed with frozen internal state variables. If the trial state violates yield admissibility, an implicit backward Euler corrector is executed. As formulated by Aravas (1987) and detailed by Zhang (1995), decoupling the return mapping into hydrostatic and deviatoric directions reduces the multi-dimensional tensor return mapping to two coupled scalar equations governing incremental hydrostatic plastic strain \Delta \varepsilon_p and equivalent plastic strain \Delta \varepsilon_q. Solving this 2x2 nonlinear system updates the Cauchy stress tensor, void volume fraction, and matrix equivalent plastic strain. - -## 2. Mathematical Formulation - -**GTN Hydrostatic and Deviatoric Stress Return Relations** -$$ -p = p^{tr} + K \Delta \varepsilon_p, \quad q = q^{tr} - 3G \Delta \varepsilon_q -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 33_ - -**GTN Plastic Flow Potential Derivatives** -$$ -\Delta \varepsilon_p = -\Delta \lambda \frac{\partial \Phi}{\partial p}, \quad \Delta \varepsilon_q = \Delta \lambda \frac{\partial \Phi}{\partial q} -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 33; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 3_ - -**Matrix Plastic Work Equivalence Relation** -$$ -(1 - f) \sigma_0 \Delta \bar{\varepsilon}^p = \bm{\sigma} : \Delta \bm{\varepsilon}^p = -p \Delta \varepsilon_p + q \Delta \varepsilon_q -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 33; Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf p. 249_ - -**Void Volume Fraction Incremental Growth** -$$ -\Delta f = (1 - f) \Delta \varepsilon_p + A_{nuc} \Delta \bar{\varepsilon}^p -$$ -_Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 3; Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf p. 249_ - -**Notation:** -p: hydrostatic pressure (-1/3 tr(\bm{\sigma})); q: equivalent von Mises stress; p^{tr}, q^{tr}: elastic trial pressure and equivalent stress; K: bulk modulus; G: shear modulus; \Delta \varepsilon_p: hydrostatic plastic strain increment; \Delta \varepsilon_q: equivalent plastic strain increment; \Delta \lambda: discrete plastic multiplier; \Phi: GTN yield function; f: void volume fraction; \sigma_0: matrix flow stress; \bar{\varepsilon}^p: matrix equivalent plastic strain. - - -## 3. Algorithmic Implementation - -**Aravas Two-Variable GTN Implicit Return-Mapping Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given converged state at } t_n\text{: } \bm{\sigma}^n, \bar{\varepsilon}^p_n, f_n \text{ and strain increment } \Delta \bm{\varepsilon}$ -\State $\bm{\sigma}^{tr} = \bm{\sigma}^n + \mathbf{D}^e : \Delta \bm{\varepsilon}, \quad p^{tr} = -\frac{1}{3}\mathrm{tr}(\bm{\sigma}^{tr}), \quad \bm{s}^{tr} = \bm{\sigma}^{tr} + p^{tr}\mathbf{I}, \quad q^{tr} = \sqrt{\frac{3}{2}\bm{s}^{tr}:\bm{s}^{tr}}$ -\State $\text{Evaluate trial yield function } \Phi^{tr} = \Phi(p^{tr}, q^{tr}, f_n, \bar{\varepsilon}^p_n)$ -\If{$\Phi^{tr} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{tr}, \quad f_{n+1} = f_n, \quad \bar{\varepsilon}^p_{n+1} = \bar{\varepsilon}^p_n$ -\Return $\text{Step is elastic; return trial state}$ -\Else -\EndIf -\While{$\|\bm{R}(\Delta \varepsilon_p^{(k)}, \Delta \varepsilon_q^{(k)})\| > \text{TOL}$} -\State $p^{(k)} = p^{tr} + K \Delta \varepsilon_p^{(k)}, \quad q^{(k)} = q^{tr} - 3G \Delta \varepsilon_q^{(k)}$ -\State $\Delta \bar{\varepsilon}^{p(k)} = \frac{-p^{(k)} \Delta \varepsilon_p^{(k)} + q^{(k)} \Delta \varepsilon_q^{(k)}}{(1 - f^{(k)}) \sigma_0}$ -\State $f^{(k+1)} = f_n + (1 - f^{(k)}) \Delta \varepsilon_p^{(k)} + A_{nuc} \Delta \bar{\varepsilon}^{p(k)}$ -\State $R_1 = \Delta \varepsilon_p^{(k)} \frac{\partial \Phi}{\partial q} + \Delta \varepsilon_q^{(k)} \frac{\partial \Phi}{\partial p}, \quad R_2 = \Phi(p^{(k)}, q^{(k)}, f^{(k+1)}, \bar{\varepsilon}_n^p + \Delta \bar{\varepsilon}^{p(k)})$ -\State $\text{Solve } 2 \times 2 \text{ linear system } \mathbf{J} \begin{bmatrix} \delta \Delta \varepsilon_p \\ \delta \Delta \varepsilon_q \end{bmatrix} = -\begin{bmatrix} R_1 \\ R_2 \end{bmatrix} \text{ and update unknowns}$ -\EndWhile -\State $\bm{n} = \frac{3}{2 q^{tr}} \bm{s}^{tr}, \quad \bm{s}_{n+1} = q_{n+1} \frac{2}{3} \bm{n}, \quad \bm{\sigma}_{n+1} = \bm{s}_{n+1} - p_{n+1} \mathbf{I}$ -\Return $\text{Return updated stress } \bm{\sigma}_{n+1}, \text{ porosity } f_{n+1}, \text{ and plastic strain } \bar{\varepsilon}^p_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 33-34; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 10_ - - -## 4. Known Pitfalls - -- **Overflow from Rapid Cosh Growth at High Hydrostatic Triaxiality**: Evaluating the GTN yield function \Phi at high hydrostatic pressures without numerical safeguards causes exponential growth in the \cosh(\frac{3 q_2 p}{2 \sigma_0}) term, leading to floating-point overflow or divergence in Newton-Raphson iterations for poor initial guesses. _(Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 3, 6; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 43)_ -- **Unphysical Singularity as Porosity Approaches Void Coalescence**: Allowing void volume fraction f to approach complete matrix material loss (f \to 1) in the matrix work-equivalence denominator (1-f)\sigma_0 produces division by zero and matrix ill-conditioning; capping porosity at an upper threshold preserves numerical robustness. _(Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 6; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 33)_ -- **Spurious Stress Direction Evolution in Deviatoric Projection**: Assuming the deviatoric stress direction \bm{n} changes during return mapping introduces tensor integration errors; in isotropic pressure-dependent return mapping, \bm{n}_{n+1} is strictly parallel to the trial deviatoric direction \bm{n}^{tr} = \frac{3}{2 q^{tr}} \bm{s}^{tr}. _(Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 33; Kim_FEA for Elastoplastic Problems.pdf p. 252)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-shear-extension.md b/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-shear-extension.md deleted file mode 100644 index 2d50257..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-shear-extension.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: damage-gtn-shear-extension -title: GTN Shear Modifications (Nahshon-Hutchinson) -domain: computational-mechanics -subdomain: damage -tags: -- damage -- gtn -- nahshon-hutchinson -- shear-damage -- lode-angle -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-gtn-void-evolution - type: refines - weight: 1.0 -- to: damage-gtn-yield-function - type: requires - weight: 0.9 -- to: plasticity-lode-triaxiality - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# GTN Shear Modifications (Nahshon-Hutchinson) - -## Summary - -GTN shear modifications extend the classical Gurson-Tvergaard-Needleman model to account for shear-dominated void growth using a Lode parameter-dependent evolution rule. - -## 1. Core Concept - -Classical Gurson-Tvergaard-Needleman (GTN) porous plasticity models void growth solely driven by volumetric hydrostatic plastic dilation, predicting zero void growth under pure shear stress states (zero triaxiality). The Nahshon-Hutchinson extension modifies the void volume fraction rate equation by introducing a Lode-angle-dependent shear void growth term. Governed by a dimensionless shear coefficient k_w and a stress-state parameter \omega(\bm{\sigma}) = 1 - L^2, this modification enables void growth under low-triaxiality shear loading paths while preserving classical GTN behavior under axisymmetric tension and compression. - -## 2. Mathematical Formulation - -**Augmented GTN Void Volume Fraction Evolution Rate** -$$ -\dot{f} = \dot{f}_{growth} + \dot{f}_{nucleation} + \dot{f}_{shear} -$$ -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 234; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 297-298_ - -**Nahshon-Hutchinson Shear Void Growth Evolution Rule** -$$ -\dot{f}_{shear} = k_w f \omega(\bm{\sigma}) \dot{\bar{\varepsilon}}^p, \quad \omega(\bm{\sigma}) = 1 - \left(\frac{27 J_3}{2 \sigma_{eq}^3}\right)^2 = 1 - L^2 -$$ -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 234; Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 609_ - -**Normalized Lode Parameter Definition** -$$ -L = \frac{27 J_3}{2 \sigma_{eq}^3} = \frac{2 \sigma_2 - \sigma_1 - \sigma_3}{\sigma_1 - \sigma_3} -$$ -_Source: Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 609; Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 536_ - -**Lode Stress-State Parameter Bounds** -$$ -\omega(\bm{\sigma}) = 1 - L^2 \in [1] -$$ -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 234; Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 609_ - -**Notation:** -\dot{f}: total void volume fraction rate; \dot{f}_{growth}: volumetric void growth rate; \dot{f}_{nucleation}: void nucleation rate; \dot{f}_{shear}: shear void growth rate; k_w: shear void growth parameter; f: void volume fraction; \omega(\bm{\sigma}): Lode stress-state function; L: normalized Lode parameter; J_3: third invariant of deviatoric stress tensor \bm{s}; \sigma_{eq}: equivalent von Mises stress; \sigma_1, \sigma_2, \sigma_3: principal Cauchy stresses; \dot{\bar{\varepsilon}}^p: equivalent matrix plastic strain rate. - - -## 3. Algorithmic Implementation - -**GTN Shear Extension Void Evolution Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given stress tensor } \bm{\sigma}_{n+1}, \text{ current porosity } f_n, \text{ matrix plastic strain increment } \Delta \bar{\varepsilon}^p, \text{ and shear growth parameter } k_w$ -\State $\bm{s} = \bm{\sigma}_{n+1} - \frac{1}{3}\mathrm{tr}(\bm{\sigma}_{n+1})\mathbf{I}, \quad \sigma_{eq} = \sqrt{\frac{3}{2}\bm{s}:\bm{s}}, \quad J_3 = \det(\bm{s})$ -\If{$\sigma_{eq} > 0$} -\State $L = \frac{27 J_3}{2 \sigma_{eq}^3}, \quad \omega(\bm{\sigma}) = 1 - L^2$ -\Else -\EndIf -\State $\Delta f_{growth} = (1 - f_n) \Delta \varepsilon_p$ -\State $\Delta f_{shear} = k_w f_n \omega(\bm{\sigma}) \Delta \bar{\varepsilon}^p$ -\State $\Delta f_{nuc} = A_{nuc} \Delta \bar{\varepsilon}^p$ -\State $f_{n+1} = f_n + \Delta f_{growth} + \Delta f_{shear} + \Delta f_{nuc}$ -\Return $\text{Return updated void volume fraction } f_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 234, 238; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 297-298_ - - -## 4. Known Pitfalls - -- **Indeterminacy of Lode Parameter at Purely Hydrostatic States**: Evaluating the Lode parameter L = 27 J_3 / (2 \sigma_{eq}^3) as equivalent stress approaches zero (\sigma_{eq} \to 0) causes division by zero; implementations must set \omega(\bm{\sigma}) = 0 when \sigma_{eq} falls below a numerical tolerance. _(Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 234; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 34)_ -- **Overpredicting Softening in Complex Low-Triaxiality Stress Paths**: Calibrating the shear growth parameter k_w solely on simple shear experiments can overestimate void growth and premature material softening during combined shear-compression or non-proportional loading paths. _(Source: Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 558, 567; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 297)_ -- **Spurious Void Creation in Void-Free Matrix Material**: Because the shear void growth rate \dot{f}_{shear} is proportional to the current porosity f, setting an initial porosity of zero (f_0 = 0) without void nucleation suppresses shear void growth entirely. _(Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 234; Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf p. 249)_ - -## References - -- Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf -- Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf -- Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-void-evolution.md b/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-void-evolution.md deleted file mode 100644 index 870b4b5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-void-evolution.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -id: damage-gtn-void-evolution -title: GTN Void Nucleation, Growth & Coalescence -domain: computational-mechanics -subdomain: damage -tags: -- damage -- gtn -- porosity -- chu-needleman -- coalescence -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-gtn-yield-function - type: requires - weight: 1.0 -- to: damage-gtn-shear-extension - type: feeds-into - weight: 1.0 -- to: damage-gtn-return-mapping - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# GTN Void Nucleation, Growth & Coalescence - -## Summary - -GTN void evolution governs ductile material damage through volumetric void growth, strain- or stress-controlled void nucleation, and Tvergaard-Needleman void coalescence acceleration. - -## 1. Core Concept - -In the Gurson-Tvergaard-Needleman (GTN) porous plasticity model, void volume fraction evolution drives isotropic material damage and strain softening. Total void growth comprises volumetric plastic expansion of existing voids and the nucleation of new micro-voids from second-phase inclusions, typically governed by Chu and Needleman's normal distribution law. As plastic deformation progresses, inter-void matrix tearing triggers void coalescence at a critical porosity threshold f_c, modeled either through Tvergaard and Needleman's bilinear effective porosity function f^*(f) or gradient-enhanced phase-field driving forces, rapidly degrading stress-carrying capacity until complete material failure. - -## 2. Mathematical Formulation - -**Total Void Volume Fraction Evolution Rate** -$$ -\dot{f} = \dot{f}_{growth} + \dot{f}_{nucleation} -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 36; Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf p. 251_ - -**Chu-Needleman Strain-Controlled Void Nucleation Rule** -$$ -\dot{f}_{nucleation} = A \dot{\bar{\varepsilon}}^p, \quad A = \frac{f_N}{S_N \sqrt{2\pi}} \exp\left[ -\frac{1}{2} \left( \frac{\bar{\varepsilon}^p - \varepsilon_N}{S_N} \right)^2 \right] -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 36; Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf p. 251_ - -**Matrix Plastic Work Equivalence Relation** -$$ -\bm{\sigma} : \dot{\bm{\varepsilon}}^p = (1 - f) \sigma_0 \dot{\bar{\varepsilon}}^p -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 36; Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf p. 251_ - -**Tvergaard-Needleman Bilinear Void Coalescence Function** -$$ -f^*(f) = \begin{cases} f & \text{for } f \le f_c \\ f_c + K_f (f - f_c) & \text{for } f > f_c \end{cases}, \quad K_f = \frac{f_u^* - f_c}{f_F - f_c} -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 37_ - -**Notation:** -\dot{f}: total void volume fraction rate; \dot{f}_{growth}: volumetric void growth rate; \dot{f}_{nucleation}: void nucleation rate; f: void volume fraction (porosity); f^*: effective void volume fraction; f_c: critical void volume fraction for coalescence onset; f_F: final failure void volume fraction; f_u^*: ultimate effective void volume fraction (1/q_1); K_f: void coalescence acceleration factor; f_N: volume fraction of void-nucleating particles; \varepsilon_N: mean void nucleation strain; S_N: standard deviation of nucleation strain; A: strain-controlled nucleation scaling coefficient; \bm{\sigma}: macroscopic Cauchy stress tensor; \dot{\bm{\varepsilon}}^p: macroscopic plastic strain rate tensor; \sigma_0: matrix flow stress; \dot{\bar{\varepsilon}}^p: matrix equivalent plastic strain rate. - - -## 3. Algorithmic Implementation - -**GTN Void Evolution and Coalescence Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given matrix plastic strain increment } \Delta \bar{\varepsilon}^p, \text{ macroscopic hydrostatic plastic strain increment } \Delta \varepsilon_p, \text{ and previous void volume fraction } f_n$ -\State $\Delta f_{growth} = (1 - f_n) \Delta \varepsilon_p$ -\State $A = \frac{f_N}{S_N \sqrt{2\pi}} \exp\left[ -\frac{1}{2} \left( \frac{\bar{\varepsilon}^p_n - \varepsilon_N}{S_N} \right)^2 \right]$ -\State $\Delta f_{nuc} = A \Delta \bar{\varepsilon}^p$ -\State $f_{n+1} = f_n + \Delta f_{growth} + \Delta f_{nuc}$ -\If{$f_{n+1} \le f_c$} -\State $f^*_{n+1} = f_{n+1}$ -\Else -\State $f^*_{n+1} = f_c + K_f (f_{n+1} - f_c)$ -\EndIf -\If{$f^*_{n+1} \ge q_1^{-1}$} -\State $f^*_{n+1} = q_1^{-1}$ -\State $\text{Material point reaches complete failure threshold; set stress to zero}$ -\EndIf -\Return $\text{Return updated void volume fraction } f_{n+1} \text{ and effective porosity } f^*_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 36-37; Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf p. 251_ - - -## 4. Known Pitfalls - -- **Division by Zero in Matrix Work Equivalence Near Complete Void Failure**: Evaluating matrix equivalent plastic strain increments using macro-micro plastic work equivalence \dot{\bar{\varepsilon}}^p = (\bm{\sigma} : \dot{\bm{\varepsilon}}^p) / [(1-f)\sigma_0] as porosity approaches complete loss of material (f \to 1) causes division by zero and numerical instability, requiring porosity capping or effective porosity regularization f^*. _(Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 36-37; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 6)_ -- **Pathological Mesh Sensitivity in Local Void Growth Without Regularization**: Modeling local void growth and coalescence in rate-independent continuum plasticity without gradient enhancements or phase-field regularization causes severe mesh dependency, where localized void failure concentrates within a single element layer. _(Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 291-292; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 225, 229)_ -- **Unphysical Zero Nucleation in Clean Alloys Without Initial Porosity**: Assuming zero initial void volume fraction (f_0 = 0) while omitting strain-controlled or stress-controlled void nucleation suppresses void evolution entirely under volumetric plastic strain, failing to predict ductile fracture in inclusion-sparse alloys. _(Source: Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf p. 249, 251; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 36)_ - -## References - -- Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-yield-function.md b/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-yield-function.md deleted file mode 100644 index da4e093..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-gtn-yield-function.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -id: damage-gtn-yield-function -title: GTN Yield Function -domain: computational-mechanics -subdomain: damage -tags: -- damage -- gtn -- porous-plasticity -- yield-function -- tvergaard -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-continuum-framework - type: refines - weight: 0.9 -- to: plasticity-von-mises - type: refines - weight: 0.9 -- to: damage-gtn-void-evolution - type: feeds-into - weight: 1.0 -- to: damage-gtn-return-mapping - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# GTN Yield Function - -## Summary - -GTN yield function models pressure-dependent porous plasticity by coupling equivalent von Mises stress, hydrostatic pressure, and void volume fraction. - -## 1. Core Concept - -The Gurson-Tvergaard-Needleman (GTN) yield function extends classical J_2 von Mises plasticity to porous ductile metals by introducing hydrostatic pressure dependence and void volume fraction (porosity) as an isotropic damage parameter. Originally derived by Gurson (1977) via micromechanical analysis of a unit cell containing a spherical void, the yield condition was subsequently modified by Tvergaard and Needleman through parameters q_1, q_2, q_3 to account for inter-void interaction effects. Hydrostatic tension accelerates plastic yield and void expansion, whereas hydrostatic compression suppresses void growth. In the limit of zero porosity, the GTN yield surface reduces identically to the standard von Mises yield criterion. - -## 2. Mathematical Formulation - -**Gurson-Tvergaard-Needleman Yield Function** -$$ -\Phi(\bm{\sigma}, \sigma_0, f) = \frac{q^2}{\sigma_0^2} + 2 q_1 f \cosh\left( \frac{3 q_2 p}{2 \sigma_0} \right) - 1 - q_3 f^2 = 0 -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 36; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 229_ - -**Original Gurson Yield Condition** -$$ -\Phi(\bm{\sigma}, \bar{\sigma}, f) = \frac{\sigma_e^2}{\bar{\sigma}^2} + 2 f \cosh\left( \frac{\sigma_k^k}{2 \bar{\sigma}} \right) - 1 - f^2 = 0 -$$ -_Source: Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf p. 249_ - -**Normal to the GTN Yield Surface (Flow Direction)** -$$ -\bm{N} = \frac{\partial \Phi}{\partial \bm{\sigma}} = \frac{3}{\sigma_0^2} \bm{s} - \frac{q_1 q_2 f}{\sigma_0} \sinh\left( \frac{3 q_2 p}{2 \sigma_0} \right) \mathbf{I} -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 33, 43; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 295-296_ - -**Pure Matrix von Mises Limit** -$$ -\lim_{f \to 0} \Phi(\bm{\sigma}, \sigma_0, f) = \frac{q^2}{\sigma_0^2} - 1 = 0 \implies q = \sigma_0 -$$ -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 36; Kim_FEA for Elastoplastic Problems.pdf p. 255_ - -**Notation:** -q: equivalent von Mises stress; p: hydrostatic pressure (-1/3 tr(\bm{\sigma})); \bm{\sigma}: macroscopic Cauchy stress tensor; \bm{s}: deviatoric Cauchy stress tensor; \sigma_0, \bar{\sigma}: matrix yield/flow stress; f: void volume fraction (porosity); q_1, q_2, q_3: Tvergaard GTN constitutive fitting parameters; \bm{N}: plastic flow direction tensor. - - -## 3. Algorithmic Implementation - -**GTN Yield Admissibility Check Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given trial stress tensor } \bm{\sigma}^{tr}, \text{ matrix flow stress } \sigma_0, \text{ current porosity } f_n, \text{ and GTN parameters } q_1, q_2, q_3$ -\State $p^{tr} = -\frac{1}{3}\mathrm{tr}(\bm{\sigma}^{tr}), \quad \bm{s}^{tr} = \bm{\sigma}^{tr} + p^{tr}\mathbf{I}, \quad q^{tr} = \sqrt{\frac{3}{2}\bm{s}^{tr}:\bm{s}^{tr}}$ -\State $\Phi^{tr} = \frac{(q^{tr})^2}{\sigma_0^2} + 2 q_1 f_n \cosh\left( \frac{3 q_2 p^{tr}}{2 \sigma_0} \right) - 1 - q_3 f_n^2$ -\If{$\Phi^{tr} \le 0$} -\State $\text{Accept step as purely elastic; set } \bm{\sigma}_{n+1} = \bm{\sigma}^{tr}$ -\Return $\text{Return elastic trial state}$ -\Else -\EndIf -\Return $\text{Return yield violation state } \Phi^{tr} > 0$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 33, 36; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 234_ - - -## 4. Known Pitfalls - -- **Floating-Point Overflow from Rapid Cosh Term Growth**: Evaluating the GTN yield condition \Phi at high hydrostatic tensile pressures without bounding the argument of \cosh(\frac{3 q_2 p}{2 \sigma_0}) causes exponential growth and floating-point overflow during local Newton-Raphson iterations. _(Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 295-296; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 43)_ -- **Inappropriate Tvergaard Parameter Calibration Across Material Classes**: Assuming fixed universal values for Tvergaard parameters (q_1, q_2, q_3) across all metals leads to inaccurate yield surface predictions; parameters must be calibrated for specific matrix materials (e.g., q_1 = 1.5, q_2 = 1.15 for steel versus q_1 = 1.25, q_2 = 0.95 for aluminum or copper alloys). _(Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 229; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 297)_ -- **Ocurrence of Zero Stress Carrying Capacity at High Porosity Limits**: When void volume fraction reaches f = 1/q_1, all stress components must vanish to satisfy the GTN yield condition (\Phi = 0), causing severe matrix ill-conditioning and singular stiffness matrices unless regulated by phase-field or capping thresholds. _(Source: Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 36; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 294-297)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Chu and Needleman - 1980 - Void Nucleation Effects in Biaxially Stretched Sheets.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-johnson-cook-failure.md b/packages/akms/src/akms/_bundled/global_nodes/damage-johnson-cook-failure.md deleted file mode 100644 index c419564..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-johnson-cook-failure.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: damage-johnson-cook-failure -title: Johnson-Cook Fracture Model -domain: computational-mechanics -subdomain: damage -tags: -- damage -- johnson-cook -- ductile-fracture -- element-erosion -- rate-dependent -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-continuum-framework - type: refines - weight: 0.9 -- to: plasticity-johnson-cook - type: feeds-into - weight: 1.0 -- to: plasticity-lode-triaxiality - type: requires - weight: 0.9 -- to: damage-element-erosion - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Johnson-Cook Fracture Model - -## Summary - -Johnson-Cook fracture model formulates rate- and temperature-dependent ductile damage evolution where a scalar damage variable tracks plastic strain accumulation normalized by a stress-state and temperature-dependent failure strain. - -## 1. Core Concept - -The Johnson-Cook damage model extends finite-strain viscoplasticity by incorporating a scalar damage history variable D in [1] to represent dynamic material degradation and loss of load-carrying capacity. Undamaged material corresponds to D = 0, whereas D = 1 indicates complete failure where Cauchy stress vanishes. Damage evolution is governed by the rate equation \dot{D} = \dot{\bar{\varepsilon}} / \varepsilon_f, where \bar{\varepsilon} is equivalent plastic strain and \varepsilon_f is the failure strain threshold depending on hydrostatic pressure, strain rate, and temperature. In computational physics codes and inelastic equations of state (IEOS), Johnson-Cook damage couples with Helmholtz free energy potentials to model high-strain-rate impact and shock wave propagation. - -## 2. Mathematical Formulation - -**Johnson-Cook Scalar Damage Evolution Rate** -$$ -\dot{D} = \frac{\dot{\bar{\varepsilon}}}{\varepsilon_f} -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 311, 312_ - -**Johnson-Cook Plastic Flow Strain Energy Function** -$$ -Y(\bar{\varepsilon}, T) = \left[ A + B \bar{\varepsilon}^N \right] \left[ 1 - \left( \theta(T) \right)^M \right], \quad \theta(T) = \frac{T - T_r}{T_M - T_r} -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 309, 310; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 245_ - -**Inelastic Equation of State (IEOS) Damage Potential Relation** -$$ -\bm{\sigma} = J^{-1} \frac{\partial \tilde{\Psi}}{\partial \bm{\varepsilon}^e}, \quad \tilde{\Psi} = \tilde{\Psi}(\bm{\varepsilon}^e, D, T) -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 310, 312-314_ - -**Consistency Condition for Damaged Inelastic Response** -$$ -\tilde{F}(\bm{\tau}, \bar{\varepsilon}, D, T) = \bar{\tau} - (1 - D) Y(\bar{\varepsilon}, T) = 0 -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 310-314_ - -**Notation:** -D: scalar damage parameter (0 \le D \le 1); \dot{\bar{\varepsilon}}: equivalent plastic strain rate; \varepsilon_f: failure strain threshold; Y: flow stress function; A, B, N, M: Johnson-Cook material strength parameters; T: absolute temperature; T_r: reference room temperature; T_M: melting temperature; \theta(T): homologous temperature; \bm{\sigma}: Cauchy stress tensor; \bm{\tau}: Kirchhoff stress tensor; \bar{\tau}: equivalent von Mises Kirchhoff stress; \tilde{\Psi}: damage-degraded Helmholtz free energy density; J: elastic volumetric Jacobian ratio. - - -## 3. Algorithmic Implementation - -**Johnson-Cook Plasticity and Damage Time Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: elastic strain } \bm{\varepsilon}^e_n, \text{ equivalent plastic strain } \bar{\varepsilon}_n, \text{ damage } D_n, \text{ temperature } T_n, \text{ and deformation gradient increment } \mathbf{F}$ -\State $\text{Compute trial elastic strain } \bm{\varepsilon}^{e,tr} = \bm{\varepsilon}^e_n + \operatorname{sym}(\nabla \Delta \bm{u}) \text{ and trial Kirchhoff stress } \bm{\tau}^{tr} = \frac{\partial \tilde{\Psi}}{\partial \bm{\varepsilon}^{e,tr}}$ -\State $\theta = \frac{T_n - T_r}{T_M - T_r}, \quad Y_n = [A + B (\bar{\varepsilon}_n)^N][1 - \theta^M]$ -\State $\tilde{F}^{tr} = \bar{\tau}^{tr} - (1 - D_n) Y_n$ -\If{$\tilde{F}^{tr} \le 0$} -\State $\bm{\sigma}_{n+1} = J^{-1} \bm{\tau}^{tr}, \quad \bar{\varepsilon}_{n+1} = \bar{\varepsilon}_n, \quad D_{n+1} = D_n$ -\Return $\text{Step is elastic; accept trial state}$ -\Else -\EndIf -\State $\Delta \bar{\varepsilon} = \Delta \lambda, \quad \bar{\varepsilon}_{n+1} = \bar{\varepsilon}_n + \Delta \bar{\varepsilon}$ -\State $\Delta D = \frac{\Delta \bar{\varepsilon}}{\varepsilon_f(p, \dot{\bar{\varepsilon}}, T)}, \quad D_{n+1} = \min(D_n + \Delta D, 1.0)$ -\State $\bm{\sigma}_{n+1} = (1 - D_{n+1}) J^{-1} \bm{\tau}_{n+1}$ -\Return $\text{Return updated stress } \bm{\sigma}_{n+1}, \text{ equivalent plastic strain } \bar{\varepsilon}_{n+1}, \text{ and damage } D_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 310-316_ - - -## 4. Known Pitfalls - -- **Uncoupled Damage Integration and Unphysical Stress Growth**: Updating Johnson-Cook damage D independently from plastic yield consistency allows equivalent stress to increase due to strain hardening even as damage approaches unity, predicting unphysical energy dissipation and numerical instability. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 470-471; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 182-184)_ -- **Singularity in Energy Potential Derivatives as Damage Approaches Unity**: Evaluating elastic stress or tangent operators as damage approaches complete material failure (D \to 1) without proper lower bounds causes division by zero and matrix ill-conditioning in finite element solvers. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 312-314; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 183-184)_ -- **Omission of Pressure and Strain-Rate Sensitivity in Constant Failure Strain Approximations**: Assuming a constant failure strain \varepsilon_f independent of pressure, strain rate, and temperature oversimplifies material response, failing to capture spallation or shear band localization under dynamic impact loading. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 311; Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 4, 8)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-nonlocal-gradient.md b/packages/akms/src/akms/_bundled/global_nodes/damage-nonlocal-gradient.md deleted file mode 100644 index 0cc1e0f..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-nonlocal-gradient.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: damage-nonlocal-gradient -title: Nonlocal Gradient Damage Regularization -domain: computational-mechanics -subdomain: damage -tags: -- damage -- nonlocal -- gradient -- regularization -- mesh-objectivity -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-continuum-framework - type: refines - weight: 0.7 -- to: damage-gtn-void-evolution - type: feeds-into - weight: 0.5 -- to: fem-tl-weak-form - type: requires - weight: 1.0 -- to: damage-nonlocal-integral - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Nonlocal Gradient Damage Regularization - -## Summary - -Nonlocal gradient damage regularization restores elliptic boundary value problems under strain-softening by introducing an internal length scale via a differential Helmholtz-type PDE for nonlocal strain. - -## 1. Core Concept - -Local continuum damage models undergoing strain-softening lose ellipticity in static problems and hyperbolicity in dynamic problems, leading to pathological mesh sensitivity where energy dissipation vanishes as the finite element mesh is refined. Nonlocal gradient damage regularization resolves this ill-posedness by formulating an implicit differential equation for a nonlocal equivalent strain field \bar{\varepsilon}, governed by an internal material length scale \ell. By coupling the local stress-strain update to the nonlocal strain field via a monolithic two-field finite element formulation, the width of the localization band is controlled independently of element size, preserving mesh objectivity and physical energy dissipation. - -## 2. Mathematical Formulation - -**Implicit Helmholtz Gradient Nonlocal Strain Equation** -$$ -\bar{\varepsilon} - c \nabla^2 \bar{\varepsilon} = \tilde{\varepsilon}, \quad c = \frac{1}{2} \ell^2 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 212_ - -**Gradient Damage Boundary Condition** -$$ -\nabla \bar{\varepsilon} \cdot \mathbf{n} = 0 \quad \text{on } S -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 212-213_ - -**Monolithic Two-Field Linearized Finite Element System** -$$ -\begin{bmatrix} \mathbf{K}_{aa} & \mathbf{K}_{ae} \\ \mathbf{K}_{ea} & \mathbf{K}_{ee} \end{bmatrix} \begin{bmatrix} d\mathbf{a} \\ d\mathbf{e} \end{bmatrix} = \begin{bmatrix} \mathbf{f}_a^{ext} - \mathbf{f}_a^{int} \\ \mathbf{f}_e^{int} - \mathbf{K}_{ee} \mathbf{e} \end{bmatrix} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 213_ - -**Coupled Gradient Stiffness Sub-Block Definitions** -$$ -\mathbf{K}_{aa} = \int_V (1 - \omega) \mathbf{B}^T \mathbf{D}^e \mathbf{B} dV, \quad \mathbf{K}_{ae} = \int_V q \mathbf{B}^T \mathbf{D}^e \bm{\varepsilon} \bar{\mathbf{H}} dV, \quad \mathbf{K}_{ee} = \int_V \left( \bar{\mathbf{H}}^T \bar{\mathbf{H}} + c \bar{\mathbf{B}}^T \bar{\mathbf{B}} \right) dV -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 213_ - -**Notation:** -\bar{\varepsilon}: nonlocal equivalent strain scalar field; \tilde{\varepsilon}: local strain-derived equivalent strain; \ell: internal material length scale parameter; c: gradient parameter (1/2 \ell^2); \mathbf{n}: outward boundary normal vector; \mathbf{a}: nodal displacement degree of freedom vector; \mathbf{e}: nodal nonlocal strain degree of freedom vector; \mathbf{K}_{aa}, \mathbf{K}_{ae}, \mathbf{K}_{ea}, \mathbf{K}_{ee}: sub-blocks of the monolithic gradient tangent stiffness matrix; \mathbf{B}: standard strain-displacement interpolation matrix; \bar{\mathbf{H}}: shape function array for nonlocal strain interpolation; \bar{\mathbf{B}}: spatial gradient matrix of \bar{\mathbf{H}}; \omega: scalar damage parameter; \kappa: historical maximum nonlocal strain. - - -## 3. Algorithmic Implementation - -**Implicit Gradient Damage Monolithic Newton-Raphson Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given displacement field } \mathbf{a}_j, \text{ nonlocal strain } \mathbf{e}_j, \text{ damage history } \kappa_j, \text{ and external force increment } \Delta \mathbf{f}_a^{ext}$ -\While{$\|\mathbf{r}_a\| > \text{TOL} \quad \text{or} \quad \|\mathbf{r}_e\| > \text{TOL}$} -\State $\bm{\varepsilon}_{j+1} = \mathbf{B} \mathbf{a}_{j+1}, \quad \tilde{\varepsilon}_{j+1} = \tilde{\varepsilon}(\bm{\varepsilon}_{j+1}), \quad \bar{\varepsilon}_{j+1} = \bar{\mathbf{H}} \mathbf{e}_{j+1}$ -\State $f = \bar{\varepsilon}_{j+1} - \kappa_j$ -\If{$f \ge 0$} -\State $\kappa_{j+1} = \bar{\varepsilon}_{j+1}, \quad q = \frac{\partial \omega}{\partial \kappa}$ -\Else -\EndIf -\State $\omega_{j+1} = \omega(\kappa_{j+1}), \quad \bm{\sigma}_{j+1} = (1 - \omega_{j+1}) \mathbf{D}^e : \bm{\varepsilon}_{j+1}$ -\State $\mathbf{K}_{aa} = \int_V (1 - \omega_{j+1}) \mathbf{B}^T \mathbf{D}^e \mathbf{B} dV, \quad \mathbf{K}_{ae} = \int_V q \mathbf{B}^T \mathbf{D}^e \bm{\varepsilon}_{j+1} \bar{\mathbf{H}} dV$ -\State $\mathbf{K}_{ea} = \int_V \bar{\mathbf{H}}^T \frac{\partial \tilde{\varepsilon}}{\partial \bm{\varepsilon}} \mathbf{B} dV, \quad \mathbf{K}_{ee} = \int_V \left( \bar{\mathbf{H}}^T \bar{\mathbf{H}} + c \bar{\mathbf{B}}^T \bar{\mathbf{B}} \right) dV$ -\State $\mathbf{r}_a = \mathbf{f}_a^{ext} - \int_V \mathbf{B}^T \bm{\sigma}_{j+1} dV, \quad \mathbf{r}_e = \int_V \bar{\mathbf{H}}^T \tilde{\varepsilon}_{j+1} dV - \mathbf{K}_{ee} \mathbf{e}_{j+1}$ -\State $\text{Solve 2-field linear system: } \begin{bmatrix} \mathbf{K}_{aa} & \mathbf{K}_{ae} \\ \mathbf{K}_{ea} & \mathbf{K}_{ee} \end{bmatrix} \begin{bmatrix} d\mathbf{a} \\ d\mathbf{e} \end{bmatrix} = \begin{bmatrix} \mathbf{r}_a \\ \mathbf{r}_e \end{bmatrix}$ -\State $\mathbf{a}_{j+1} = \mathbf{a}_{j+1} + d\mathbf{a}, \quad \mathbf{e}_{j+1} = \mathbf{e}_{j+1} + d\mathbf{e}$ -\EndWhile -\Return $\text{Return updated displacements } \mathbf{a}_{j+1}, \text{ nonlocal strains } \mathbf{e}_{j+1}, \text{ and Cauchy stress } \bm{\sigma}_{j+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 6.5, p. 213-214_ - - -## 4. Known Pitfalls - -- **Spurious Non-Symmetry in Monolithic System Matrix**: The off-diagonal coupling blocks K_ae and K_ea in implicit gradient damage are inherently non-symmetric due to the derivative of damage with respect to history q = \partial \omega / \partial \kappa; forcing a symmetric solver discards cross-coupling terms and degrades global Newton convergence. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 213)_ -- **C1-Continuity Requirements in Explicit Second-Order Gradient Models**: Evaluating second-order spatial gradients of local equivalent strain \nabla^2 \tilde{\varepsilon} directly in explicit gradient damage models requires third-order displacement derivatives, necessitating C1-continuous shape functions unless transformed into an implicit PDE. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 211-212)_ -- **Spurious Damage Broadening Near Zero-Flux Boundaries**: Enforcing the natural boundary condition \nabla \bar{\varepsilon} \cdot \mathbf{n} = 0 on non-physical boundary locations artificially forces damage profiles to remain orthogonal to domain edges, introducing artificial boundary layer broadening. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 212-213; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 290)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Sarkar - A Computationally Efficient Vectorized Implementation of Localizing Gradient Damage Method in MATLAB.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-nonlocal-integral.md b/packages/akms/src/akms/_bundled/global_nodes/damage-nonlocal-integral.md deleted file mode 100644 index 120af20..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-nonlocal-integral.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: damage-nonlocal-integral -title: Nonlocal Integral Damage Regularization -domain: computational-mechanics -subdomain: damage -tags: -- damage -- nonlocal -- integral -- regularization -- mesh-objectivity -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-continuum-framework - type: refines - weight: 0.7 -- to: damage-nonlocal-gradient - type: refines - weight: 0.7 -- to: damage-gtn-void-evolution - type: feeds-into - weight: 0.5 -- to: fem-tl-weak-form - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Nonlocal Integral Damage Regularization - -## Summary - -Nonlocal integral damage regularization restores objectivity in strain-softening continuum models by replacing local equivalent strain with a spatially weighted integral average over the domain. - -## 1. Core Concept - -In local continuum damage models, strain-softening causes ill-posedness and severe mesh sensitivity, where localization bands collapse to a single element width and dissipated energy approaches zero upon mesh refinement. Nonlocal integral damage regularization resolves this pathological behavior by defining the damage loading criterion in terms of a nonlocal equivalent strain field \bar{\varepsilon}(\bm{x}). This nonlocal strain is computed as a spatially weighted integral average of the local equivalent strain \tilde{\varepsilon}(\bm{y}) using an averaging kernel \psi(\bm{y}, \bm{x}) and a normalization factor \Omega(\bm{x}). The spatial integration introduces an internal material length scale \ell, ensuring that the failure process zone width and energy dissipation remain finite and independent of finite element discretizations. - -## 2. Mathematical Formulation - -**Nonlocal Integral Strain Averaging Equation** -$$ -\bar{\varepsilon}(\mathbf{x}) = \frac{1}{\Omega(\mathbf{x})} \int_V \psi(\mathbf{y}, \mathbf{x}) \tilde{\varepsilon}(\mathbf{y}) dV, \quad \Omega(\mathbf{x}) = \int_V \psi(\mathbf{y}, \mathbf{x}) dV -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 211_ - -**Isotropic Gaussian Spatial Weight Kernel** -$$ -\psi(s) = \frac{1}{\sqrt{2\pi} \ell} \exp\left( -\frac{s^2}{2 \ell^2} \right), \quad s = \|\mathbf{x} - \mathbf{y}\| -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 211_ - -**Discrete Numerical Quadrature for Nonlocal Strain** -$$ -\bar{\varepsilon}_{j+1}(\mathbf{x}) = \sum_i w_i \psi(\mathbf{y}_i, \mathbf{x}) \tilde{\varepsilon}_{j+1}(\mathbf{y}_i) V_{elem} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 6.4, p. 211_ - -**Nonlocal Damage Loading Criterion** -$$ -f(\bar{\varepsilon}, \kappa) = \bar{\varepsilon} - \kappa \le 0, \quad \dot{\kappa} \ge 0, \quad f \dot{\kappa} = 0 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 6.4, p. 211_ - -**Notation:** -\bar{\varepsilon}: nonlocal equivalent strain scalar field; \tilde{\varepsilon}: local equivalent strain measure; \mathbf{x}, \mathbf{y}: spatial position vectors; \psi(\mathbf{y}, \mathbf{x}): spatial averaging weight kernel function; \Omega(\mathbf{x}): spatial normalization volume factor; s: Euclidean distance \|\mathbf{x} - \mathbf{y}\|; \ell: internal material length scale; \kappa: internal damage history parameter; w_i: numerical integration weight at Gauss point i; V_{elem}: finite element volume contribution. - - -## 3. Algorithmic Implementation - -**Nonlocal Integral Damage State Update Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given total strain increment } \Delta \bm{\varepsilon}_{j+1}, \text{ previous strain } \bm{\varepsilon}_j, \text{ and previous damage history } \kappa_0$ -\State $\bm{\varepsilon}_{j+1} = \bm{\varepsilon}_j + \Delta \bm{\varepsilon}_{j+1}$ -\State $\tilde{\varepsilon}_{j+1}(\bm{x}) = \tilde{\varepsilon}(\bm{\varepsilon}_{j+1}(\bm{x})) \quad \text{at all Gauss integration points } \bm{x}$ -\For{$\text{Each Gauss integration point } \bm{x} \text{ in domain } V$} -\State $\bar{\varepsilon}_{j+1}(\bm{x}) = \sum_i w_i \psi(\bm{y}_i, \bm{x}) \tilde{\varepsilon}_{j+1}(\bm{y}_i) V_{elem}$ -\EndFor -\If{$\bar{\varepsilon}_{j+1}(\bm{x}) - \kappa_0 \ge 0$} -\State $\kappa_{j+1} = \bar{\varepsilon}_{j+1}(\bm{x})$ -\Else -\EndIf -\State $\omega_{j+1} = \omega(\kappa_{j+1})$ -\State $\bm{\sigma}_{j+1} = (1 - \omega_{j+1}) \mathbf{D}^e : \bm{\varepsilon}_{j+1}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{j+1} \text{ and history } \kappa_{j+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 6.4, p. 211_ - - -## 4. Known Pitfalls - -- **Loss of Stiffness Matrix Symmetry in Implicit Solvers**: Averaging local strain fields across neighboring elements breaks the local symmetry of the strain-displacement operator, causing the global tangential stiffness matrix to become non-symmetric and increasing bandwidth. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 211; Sarkar - A Computationally Efficient Vectorized Implementation of Localizing Gradient Damage Method in MATLAB.pdf p. 3)_ -- **Spurious Boundary Distortions from Unnormalized Weight Kernels**: Failing to normalize the spatial weight function by \Omega(\bm{x}) = \int_V \psi(\bm{y}, \bm{x}) dV near domain boundaries causes artificial reduction of nonlocal strain, resulting in unphysical damage suppression along specimen edges. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 211)_ -- **Quadratic Computational Complexity for Full Domain Integration**: Evaluating spatial integrals over all Gauss point pairs scales quadratically with the total number of integration points (O(N^2)), causing severe computational bottlenecks in large 3D finite element meshes unless truncated to local neighborhoods. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 211; Sarkar - A Computationally Efficient Vectorized Implementation of Localizing Gradient Damage Method in MATLAB.pdf p. 2-3)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Sarkar - A Computationally Efficient Vectorized Implementation of Localizing Gradient Damage Method in MATLAB.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/damage-spall.md b/packages/akms/src/akms/_bundled/global_nodes/damage-spall.md deleted file mode 100644 index cf2d480..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/damage-spall.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -id: damage-spall -title: Spall Fracture Models -domain: computational-mechanics -subdomain: damage -tags: -- damage -- spall -- dynamic-fracture -- nag -- tuler-butcher -status: established -confidence: 0.9 -source: hybrid -edges: -- to: damage-continuum-framework - type: refines - weight: 0.8 -- to: damage-element-erosion - type: feeds-into - weight: 0.9 -- to: damage-gtn-yield-function - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Spall Fracture Models - -## Summary - -Spall fracture models describe dynamic material failure and crack formation under high-velocity impact loading driven by rarefaction wave-induced dynamic tensile stresses. - -## 1. Core Concept - -Spallation is a dynamic failure mechanism occurring in ductile metals subjected to high-velocity impact or shock wave loading. When compressive shock waves reflect off free surfaces, intersecting rarefaction waves generate severe dynamic hydrostatic tensile stresses. Under these intense tensile stress states, material failure progresses through the rapid nucleation, volumetric growth, and coalescence of micro-voids in a localized spall zone. Modern computational formulations model dynamic spalling by coupling Gurson-type porous plasticity with phase-field or gradient-enhanced continuum damage mechanics, incorporating pressure-dependent bulk moduli to accurately represent material response under multi-gigapascal impact pressures. - -## 2. Mathematical Formulation - -**Pressure-Dependent Bulk Modulus (Murnaghan Approximation)** -$$ -\kappa(p) = \kappa_0 + n_0 p -$$ -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231_ - -**Phase-Field Degraded Tensile Elastic Stress Relation** -$$ -\bm{\sigma} = g(d) \bm{\sigma}^+ + \bm{\sigma}^-, \quad g(d) = (1 - d)^2 -$$ -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231_ - -**Gurson-Type Phase-Field Spall Driving Force** -$$ -\dot{d} = \frac{1}{\eta_d} \left\langle \mathcal{H} - \frac{G_c}{2 \ell_c} d + G_c \ell_c \nabla^2 d \right\rangle -$$ -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 230, 238_ - -**Phase-Field Degraded Yield Stress** -$$ -\sigma_y = g(d) \sigma_{0y} -$$ -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; p: hydrostatic pressure; \kappa(p): pressure-dependent bulk modulus; \kappa_0: initial bulk modulus; n_0: Murnaghan parameter; d: phase-field spall damage variable (0 \le d \le 1); g(d): continuous quadratic degradation function; \bm{\sigma}^+, \bm{\sigma}^-: tensile and compressive spectral stress components; \mathcal{H}: history-dependent energy driving force; G_c: fracture energy release rate; \ell_c: characteristic phase-field length scale; \eta_d: phase-field mobility/viscosity parameter; f: void volume fraction; f_c: critical void coalescence threshold; \sigma_y: degraded yield strength; \sigma_{0y}: initial yield strength. - - -## 3. Algorithmic Implementation - -**Explicit Gurson-Type Phase-Field Dynamic Spall Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_k\text{: displacement } \mathbf{u}_k, \text{ phase-field } d_k, \text{ porosity } f_k, \text{ plastic strain } \bm{\varepsilon}_k, \text{ and explicit time step } \Delta t$ -\State $\text{Compute strain increment } \Delta \bm{\varepsilon} = \operatorname{sym}(\nabla \Delta \mathbf{u}) \text{ and updated pressure } p_{k+1}$ -\State $\text{Update bulk modulus: } \kappa(p_{k+1}) = \kappa_0 + n_0 p_{k+1}$ -\State $\text{Predict trial stress } \bm{\sigma}^{pre} \text{ and evaluate GTN yield function } \Phi(p, q, f_k)$ -\If{$\Phi > 0$} -\State $\text{Solve GTN return mapping for updated plastic strain } \bm{\varepsilon}_{k+1} \text{ and porosity } f_{k+1}$ -\Else -\EndIf -\If{$f_{k+1} \ge f_c$} -\State $\text{Compute phase-field driving force } \mathcal{H}_{k+1} \text{ from plastic work and void expansion}$ -\State $\text{Solve phase-field evolution PDE for } d_{k+1} = d_k + \dot{d} \Delta t$ -\Else -\EndIf -\State $\text{Update degraded Cauchy stress: } \bm{\sigma}_{k+1} = g(d_{k+1}) \bm{\sigma}^+ + \bm{\sigma}^-$ -\Return $\text{Return updated stress } \bm{\sigma}_{k+1}, \text{ porosity } f_{k+1}, \text{ and phase-field damage } d_{k+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231, 238_ - - -## 4. Known Pitfalls - -- **Ignoring Pressure Dependence of Bulk Modulus under High Shock Pressures**: Using a constant linear elastic bulk modulus \kappa_0 under multi-gigapascal dynamic impact pressures overpredicts volumetric expansion and miscalculates shock wave velocity, distorting the location and magnitude of peak tensile rarefaction stresses in spallation zones. _(Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231)_ -- **Unsplit Elastic Energy Degradation Causing Spurious Compressive Failure**: Degrading total elastic energy uniformly without splitting tensile \bm{\sigma}^+ and compressive \bm{\sigma}^- stress components causes unphysical stiffness loss under shock compression, preventing correct wave reflection and spall zone formation. _(Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231; Meng and Tabiei - 2024 - Phase field modeling of ductile fracture with isotropic hardening and radius return method.pdf p. 281-282)_ -- **Premature Spall Crack Activation Before Void Coalescence**: Triggering macroscopic spall damage or phase-field evolution prior to reaching the critical void volume fraction threshold (f < f_c) artificially accelerates material failure during early wave propagation. _(Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 230, 238)_ - -## References - -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Meng and Tabiei - 2024 - Phase field modeling of ductile fracture with isotropic hardening and radius return method.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/elastic-anisotropic.md b/packages/akms/src/akms/_bundled/global_nodes/elastic-anisotropic.md deleted file mode 100644 index d8d7b37..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/elastic-anisotropic.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: elastic-anisotropic -title: 'Anisotropic Elasticity: Symmetries and Constants' -domain: computational-mechanics -subdomain: elasticity -tags: -- elasticity -- anisotropic -- voigt -- orthotropic -- transverse-isotropic -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-products-contractions - type: requires - weight: 1.0 -- to: composite-laminate-theory - type: feeds-into - weight: 0.5 -- to: composite-homogenization - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Anisotropic Elasticity: Symmetries and Constants - -## Summary - -Anisotropic linear elasticity defines fourth-order tensor relations mapping second-order strain tensors to stress tensors across isotropic, transversely isotropic, and orthotropic material symmetries in heterogeneous composite media. Constitutive formulations split elastic behavior into volumetric and deviatoric components for isotropic phases, or invariant stress projections for transversely isotropic plies via Gibbs free energy density functions governed by five independent elastic constants. In 3D woven composites, orthotropic symmetry relates macroscopic volume-averaged stresses and strains via a 6x6 compliance matrix parameterized by nine independent moduli. Advanced non-local continuum mechanics and state-based peridynamics utilize correspondence models to replicate full anisotropic fourth-order elasticity tensors. - -## 1. Core Concept - -Anisotropic elasticity formulates linear stress-strain relationships for materials whose mechanical response depends on spatial orientation. In isotropic media, Hooke's law splits fourth-order stiffness into bulk and shear components using volumetric and deviatoric projection tensors. For unidirectional fiber-reinforced composite laminas exhibiting transverse isotropy, five independent elastic constants—longitudinal Young's modulus E_11, transverse Young's modulus E_22, in-plane shear modulus G_12, longitudinal Poisson's ratio nu_12, and transverse Poisson's ratio nu_23—govern constitutive behavior, with transverse shear modulus G_23 constrained by G_23 = E_22 / [2(1 + nu_23)]. - -In 3D woven fabric composites and homogenized representative volume elements, material symmetry is orthotropic, characterized by nine independent elastic constants defining a symmetric 6x6 compliance matrix S*. Macroscopic volume-averaging over repeating unit cells computes effective orthotropic compliance under six independent loading conditions. In non-local continuum frameworks such as peridynamics, classical bond-based formulations restrict Poisson's ratio to fixed values (e.g., 1/4 in 3D), necessitating ordinary state-based correspondence models to accurately represent general anisotropic elasticity tensors. - -## 2. Mathematical Formulation - -**Isotropic Linear Elastic Stiffness Tensor and Projection Decomposition** -$$ -\sigma(x) = L(x) \varepsilon(x) + \alpha(x), \quad L(x) = d k(x) N_1 + 2 \mu(x) N_2 -$$ -_Source: Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf, Section 2.1, Eqs. 2.1-2.2, 2.5_ - -**Transversely Isotropic Gibbs Free Energy Density** -$$ -\psi(\tilde{\sigma}) = \frac{1}{2} \left[ \frac{\tilde{\sigma}_L^2}{E_{11}} - \frac{4 \nu_{12} \tilde{\sigma}_L \tilde{p}_T}{E_{11}} + \frac{\tilde{p}_T^2}{E_T} + \frac{\tilde{\tau}_T^2}{G_T} + \frac{\tilde{\tau}_L^2}{G_{12}} \right] -$$ -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.6, Eqs. 123-125_ - -**Orthotropic Macroscopic Compliance Homogenization Relation** -$$ -E_{ij} = S_{ijkl}^* \Sigma_{kl}, \quad \Sigma_{ij} = \frac{1}{V_{\text{RUC}}} \int_{V_{\text{RUC}}} \sigma_{ij} \, dV, \quad E_{ij} = \frac{1}{V_{\text{RUC}}} \int_{V_{\text{RUC}}} \varepsilon_{ij} \, dV -$$ -_Source: Carvelli and Poggi - 2001 - A homogenization procedure for the numerical analysis of woven fabric composites.pdf, Section 2 & 3, Eqs. 1-8_ - -**Isotropic Elastic Moduli Conversion Relations** -$$ -K = \lambda + \frac{2}{3} G, \quad E = \frac{9 K G}{3 K + G}, \quad \nu = \frac{3 K - 2 G}{2 (3 K + G)} -$$ -_Source: Hashin - THE ELASTIC MODULI OF HETEROGENEOUS MATERIALS.pdf, Section 2 & 6, Eqs. 2.7, 6.3-6.4_ - -**Notation:** -- \sigma, \varepsilon: Cauchy stress tensor and strain tensor -- L(x), M(x): Fourth-order linear elastic stiffness and compliance tensors -- k(x), \mu(x): Bulk modulus and shear modulus -- N_1, N_2: Spherical and deviatoric projection operators -- \psi(\tilde{\sigma}): Transversely isotropic Gibbs free energy density -- \tilde{\sigma}_L, \tilde{p}_T: Longitudinal stress and transverse hydrostatic stress invariants -- \tilde{\tau}_L, \tilde{\tau}_T: Longitudinal shear and transverse shear stress invariants -- E_{11}, E_{22}: Longitudinal and transverse Young's moduli -- G_{12}, G_{23}: In-plane shear modulus and transverse shear modulus -- \nu_{12}, \nu_{23}: In-plane Poisson's ratio and transverse Poisson's ratio -- \Sigma_{ij}, E_{ij}: Macroscopic stress and strain tensors averaged over repeating unit cell -- S_{ijkl}^*: Macroscopic effective orthotropic compliance matrix - - -## 3. Algorithmic Implementation - -**ComputeIsotropicElasticityTensor** -$$ -\begin{algorithmic} -\State $K = \lambda + \frac{2.0}{3.0} \mu, \quad E = \frac{9.0 K \mu}{3.0 K + \mu}, \quad \nu = \frac{3.0 K - 2.0 \mu}{2.0 (3.0 K + \mu)}$ -\State $N_1 = \frac{1.0}{d} (\delta \otimes \delta), \quad N_2 = I - N_1$ -\State $L = d \cdot K \cdot N_1 + 2.0 \mu \cdot N_2$ -\State $\sigma = L \cdot \varepsilon + \alpha$ -\State $w = 0.5 \cdot (K \cdot (\text{tr}(\varepsilon))^2 + 2.0 \mu \cdot e_{ij} e_{ij})$ -\Return $L, \sigma, w$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf, Section 2.1, Eqs. 2.1-2.2_ - -**EvaluateTransverseIsotropicGibbsEnergy** -$$ -\begin{algorithmic} -\State $\tilde{\sigma}_L = \tilde{\sigma}_{11}, \quad \tilde{p}_T = 0.5 \cdot (\tilde{\sigma}_{22} + \tilde{\sigma}_{33})$ -\State $\tilde{\tau}_L = 0.5 \cdot \sqrt{(\tilde{\sigma}_{22} - \tilde{\sigma}_{33})^2 + 4.0 \tilde{\sigma}_{23}^2}, \quad \tilde{\tau}_T = \sqrt{\tilde{\sigma}_{12}^2 + \tilde{\sigma}_{13}^2}$ -\State $E_T = \frac{E_{22}}{2.0 (1.0 - \nu_{23})}, \quad G_T = \frac{E_{22}}{2.0 (1.0 + \nu_{23})}$ -\State $\psi(\tilde{\sigma}) = 0.5 \cdot \left[ \frac{\tilde{\sigma}_L^2}{E_{11}} - \frac{4.0 \nu_{12} \tilde{\sigma}_L \tilde{p}_T}{E_{11}} + \frac{\tilde{p}_T^2}{E_T} + \frac{\tilde{\tau}_T^2}{G_T} + \frac{\tilde{\tau}_L^2}{G_{12}} \right]$ -\Return $\psi(\tilde{\sigma}), E_T, G_T$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.6, Eqs. 123-125_ - - -## 4. Known Pitfalls - -- **assuming-transverse-isotropy-independence-of-shear-modulus**: In transversely isotropic plies, treating transverse shear modulus G_23 as an independent parameter violates thermodynamic constraints; G_23 = G_T = E_22 / [2(1 + nu_23)] is strictly constrained by transverse Young's modulus E_22 and Poisson's ratio nu_23. _(Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 3.6, Eq. 125)_ -- **peridynamic-bond-based-poisson-ratio-restriction**: Using bond-based peridynamics to represent anisotropic elasticity restricts Poisson's ratio to fixed values (nu = 1/4 in 3D, nu = 1/3 in 2D plane stress); state-based correspondence models must be used to represent arbitrary anisotropic fourth-order elasticity tensors. _(Source: Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf, Section 1)_ -- **violating-positive-definiteness-in-orthotropic-compliance**: Constructing orthotropic compliance matrices without verifying positive-definiteness of the 6x6 elasticity tensor produces unphysical negative strain energy densities and solver divergence under multiaxial stress states. _(Source: Carvelli and Poggi - 2001 - A homogenization procedure for the numerical analysis of woven fabric composites.pdf, Section 2)_ - -## References - -- Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf -- Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf -- Carvelli and Poggi - 2001 - A homogenization procedure for the numerical analysis of woven fabric composites.pdf -- Hashin - THE ELASTIC MODULI OF HETEROGENEOUS MATERIALS.pdf -- Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/elastic-eos-coupling.md b/packages/akms/src/akms/_bundled/global_nodes/elastic-eos-coupling.md deleted file mode 100644 index 72443c0..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/elastic-eos-coupling.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: elastic-eos-coupling -title: Volumetric-Deviatoric Split & EOS Coupling -domain: computational-mechanics -subdomain: elasticity -tags: -- elasticity -- EOS -- voldev-split -- mie-gruneisen -- hyperelastic -status: established -confidence: 0.9 -source: hybrid -edges: -- to: elastic-anisotropic - type: refines - weight: 0.7 -- to: eos-mie-gruneisen - type: requires - weight: 1.0 -- to: pf-spallation - type: feeds-into - weight: 0.5 -- to: eos-polynomial - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Volumetric-Deviatoric Split & EOS Coupling - -## Summary - -Volumetric-deviatoric stress and strain tensor decomposition partitions isotropic continuum mechanical behavior into hydrostatic (spherical) and shear (deviatoric) components. In linear isotropic elasticity, stress and strain tensors are split into hydrostatic mean stress sigma = tr(sigma) and deviatoric stress s_ij, governed independently by bulk modulus K and shear modulus G. In composite micromechanics and multiscale continuum modeling, volumetric-deviatoric projections utilize fourth-order spherical N_1 and deviatoric N_2 tensor operators to decompose stiffness tensors. Hydrostatic stress and strain invariants drive scalar progressive damage initiation in quasi-brittle matrix subcells during manufacturing cool-down. Furthermore, in phase-field fracture formulations, strain energy is decomposed into tensile and compressive volumetric/deviatoric components or mode-specific directional energy density invariants to prevent unphysical damage under pure compressive hydrostatic loading. - -## 1. Core Concept - -Volumetric-deviatoric tensor splitting separates mechanical field responses that alter material volume from those that change geometric shape. In classical linear elasticity, Hooke's law decomposes the second-order stress tensor into isotropic mean normal stress (pressure) and deviatoric shear stress s_ij, relating them through local bulk modulus K and shear modulus G. In isotropic fourth-order elasticity, this split is expressed using spherical projection tensor N_1 = (1/d) (delta x delta) and deviatoric projection tensor N_2 = I - N_1, where total elastic stiffness L = d K N_1 + 2 G N_2. - -In multiscale composite modeling, hydrostatic equivalent stress and strain invariants govern progressive damage initiation in quasi-brittle matrix constituents (e.g., SiC matrices), where microcracking is activated by tensile volumetric dilation during thermal cool-down. In variational phase-field fracture, strain energy density is split into positive (tensile/volumetric expansion) and negative (compressive/volumetric contraction) parts using spectral strain decomposition or transversely isotropic stress invariants, ensuring degradation affects only crack-opening volumetric and shear modes. - -## 2. Mathematical Formulation - -**Isotropic Linear Elastic Volumetric-Deviatoric Stress Split** -$$ -\sigma_{ij} = \frac{\sigma}{3} \delta_{ij} + s_{ij}, \quad \varepsilon_{ij} = \frac{\varepsilon}{3} \delta_{ij} + e_{ij}, \quad \sigma = 3 K \varepsilon, \quad s_{ij} = 2 G e_{ij} -$$ -_Source: Hashin - THE ELASTIC MODULI OF HETEROGENEOUS MATERIALS.pdf, Section 2, Eqs. 2.6-2.7_ - -**Fourth-Order Stiffness Tensor Projection Decomposition** -$$ -L = d K N_1 + 2 G N_2, \quad N_1 = \frac{1}{d} (\delta \otimes \delta), \quad N_2 = I - N_1 -$$ -_Source: Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf, Section 2.1, Eq. 2.5_ - -**Isotropic Spectral Strain Energy Volumetric-Deviatoric Split** -$$ -\psi_b^{\pm} = \frac{\lambda}{2} \langle \text{tr}(\boldsymbol{\varepsilon}) \rangle_{\pm}^2 + G \, \text{tr}\left( \langle \boldsymbol{\varepsilon} \rangle_{\pm}^2 \right) -$$ -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 2.1, Eq. 19_ - -**Hydrostatic Stress-Driven Matrix Thermoelastic Damage** -$$ -r_{\text{eq}} = 3 (1 - \phi) K_0 \left[ e_{\text{eq}} - \alpha_0 \Delta T \right] \ge r_{\text{crit}}(T, \dot{\epsilon}) -$$ -_Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.2, Eqs. 1, 17_ - -**Notation:** -- \sigma_{ij}, s_{ij}: Cauchy stress tensor and deviatoric stress tensor -- \varepsilon_{ij}, e_{ij}: Total strain tensor and deviatoric strain tensor -- \sigma, \varepsilon: Trace of stress tensor and trace of strain tensor (volumetric strain) -- K, G: Bulk modulus and shear modulus -- N_1, N_2: Fourth-order spherical and deviatoric projection tensors -- \delta, I: Second-order Kronecker delta and fourth-order symmetric identity tensor -- d: Spatial dimension (2 or 3) -- \lambda: Lamé first parameter -- \psi_b^+, \psi_b^-: Tensile and compressive strain energy density splits -- \phi: Scalar degradation damage parameter -- r_{\text{eq}}, e_{\text{eq}}: Equivalent hydrostatic stress and strain invariants -- r_{\text{crit}}: Critical hydrostatic stress threshold for damage initiation -- \alpha_0: Matrix thermal expansion coefficient -- \Delta T: Temperature differential relative to reference state - - -## 3. Algorithmic Implementation - -**ComputeVolumetricDeviatoricStressSplit** -$$ -\begin{algorithmic} -\State $\sigma = \text{tr}(\sigma_{ij}) = \sigma_{11} + \sigma_{22} + \sigma_{33}$ -\State $\varepsilon = \text{tr}(\varepsilon_{ij}) = \varepsilon_{11} + \varepsilon_{22} + \varepsilon_{33}$ -\For{$i = 1 \text{ To } 3$} -\For{$j = 1 \text{ To } 3$} -\If{$i == j$} -\State $s_{ij} = \sigma_{ij} - \frac{1}{3} \sigma, \quad e_{ij} = \varepsilon_{ij} - \frac{1}{3} \varepsilon$ -\Else -\State $s_{ij} = \sigma_{ij}, \quad e_{ij} = \varepsilon_{ij}$ -\EndIf -\EndFor -\EndFor -\State $w_{\text{vol}} = \frac{1}{2} K \varepsilon^2, \quad w_{\text{dev}} = G \sum_{i,j} e_{ij} e_{ij}$ -\State $w_{\text{total}} = w_{\text{vol}} + w_{\text{dev}}$ -\Return $s_{ij}, e_{ij}, w_{\text{vol}}, w_{\text{dev}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Hashin - THE ELASTIC MODULI OF HETEROGENEOUS MATERIALS.pdf, Section 2, Eqs. 2.6-2.9_ - -**EvaluatePhaseFieldVolumetricStrainSplit** -$$ -\begin{algorithmic} -\State $\varepsilon_{\text{vol}} = \text{tr}(\boldsymbol{\varepsilon})$ -\State $\varepsilon_{\text{vol}}^+ = \max(0, \varepsilon_{\text{vol}}), \quad \varepsilon_{\text{vol}}^- = \min(0, \varepsilon_{\text{vol}})$ -\State $\psi_b^+ = \frac{1}{2} \lambda (\varepsilon_{\text{vol}}^+)^2 + G \sum_{i} (\langle \hat{\varepsilon}_i \rangle_+)^2$ -\State $\psi_b^- = \frac{1}{2} \lambda (\varepsilon_{\text{vol}}^-)^2 + G \sum_{i} (\langle \hat{\varepsilon}_i \rangle_-)^2$ -\State $\psi_{\text{degraded}} = (1 - d)^2 \psi_b^+ + \psi_b^-$ -\Return $\psi_b^+, \psi_b^-, \psi_{\text{degraded}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 2.1, Eqs. 18-20_ - - -## 4. Known Pitfalls - -- **unsplit-strain-energy-causes-compression-damage**: Failing to split strain energy into tensile (positive) and compressive (negative) volumetric parts in phase-field fracture formulations causes unphysical material damage degradation under pure compressive hydrostatic stress states. _(Source: Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf, Section 2.1)_ -- **ignoring-volumetric-thermal-dilation-microcracking**: Neglecting hydrostatic dilation induced by fiber-matrix thermal expansion mismatch during post-manufacturing cool-down overpredicts initial composite laminate stiffness by at least 25% due to omitted pre-existing matrix microcracks. _(Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 3)_ -- **constant-strain-subcell-elimination-in-gmc**: Assuming constant subcell strain fields in GMC homogenization causes any subcell with zero bulk or shear stiffness (e.g., a void) to eliminate the entire row and column in which it resides unless a sub-RUC architecture is used. _(Source: Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf, Section 2.1)_ - -## References - -- Hashin - THE ELASTIC MODULI OF HETEROGENEOUS MATERIALS.pdf -- Buryachenko - 2025 - Unified Micromechanics Theory of Composites.pdf -- Borkowski and Chattopadhyay - 2015 - Multiscale model of woven ceramic matrix composites considering manufacturing induced damage.pdf -- Bui and Hu - 2021 - A review of phase-field models, fundamentals and their applications to composite laminates.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/eos-mie-gruneisen.md b/packages/akms/src/akms/_bundled/global_nodes/eos-mie-gruneisen.md deleted file mode 100644 index 239a872..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/eos-mie-gruneisen.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: eos-mie-gruneisen -title: Mie-Gruneisen EOS -domain: computational-mechanics -subdomain: eos -tags: -- eos -- mie-gruneisen -- hugoniot -- shock-physics -- gruneisen-parameter -status: established -confidence: 0.9 -source: hybrid -edges: -- to: eos-overview - type: requires - weight: 1.0 -- to: eos-polynomial - type: refines - weight: 0.8 -- to: damage-spall - type: feeds-into - weight: 0.9 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Mie-Gruneisen EOS - -## Summary - -Equation of state (EOS) formulations in shock physics and solid dynamics model pressure, volumetric deformation, and internal energy coupling within inelastic thermodynamic frameworks. - -## 1. Core Concept - -In high-velocity impact and shock-physics simulations, an Equation of State (EOS) defines the thermodynamic relationship between hydrostatic pressure, volumetric strain J = det(F_e), temperature, and internal energy density. In inelastic equation of state (IEOS) frameworks, thermodynamic potentials partition internal energy into cold compression energy E_c(J), thermal lattice energy E_l(J, T), and elastic shear strain energy. Hydrocodes compute updated pressure, temperature, and Cauchy stress by enforcing internal energy conservation alongside elastoplastic return mapping and damage degradation. - -## 2. Mathematical Formulation - -**Inelastic Equation of State Internal Energy Decomposition** -$$ -E(\bm{\varepsilon}^e, D, T) = E_c(J) + E_l(J, T) + (1 - D) \Psi_{iso}(\bm{\varepsilon}^e_{dev}) -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 309, 310_ - -**Damage-Degraded Helmholtz Energy and Cauchy Stress Relation** -$$ -\bm{\sigma} = J^{-1} \frac{\partial \tilde{\Psi}(\bm{\varepsilon}^e, D, T)}{\partial \bm{\varepsilon}^e} -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 310, 312_ - -**Pressure-Dependent Bulk Modulus (Murnaghan EOS)** -$$ -B(p) = B_0 + B_0' p \quad \text{or} \quad \kappa(p) = \kappa_0 + n_0 p -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 8; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231_ - -**Nonlinear Energy Balance Consistency Condition** -$$ -E_{n+1} - \tilde{E}(\bm{\varepsilon}^e_{n+1}, D_{n+1}, T_{n+1}) = 0 -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 312, 314_ - -**Notation:** -E: specific internal energy density; E_c(J): cold compression energy function; E_l(J, T): thermal energy function; J: elastic volumetric ratio \det(\mathbf{F}^e); \bm{\varepsilon}^e: logarithmic elastic strain tensor; D: scalar damage variable (0 \le D \le 1); \tilde{\Psi}: Helmholtz free energy density potential; \bm{\sigma}: Cauchy stress tensor; B(p), \kappa(p): pressure-dependent bulk modulus; B_0, \kappa_0: initial bulk modulus; B_0', n_0: pressure derivative parameters; p: hydrostatic pressure; T: absolute temperature. - - -## 3. Algorithmic Implementation - -**Inelastic Equation of State Hydrocode Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: elastic strain } \bm{\varepsilon}^e_n, \text{ internal energy } E_n, \text{ temperature } T_n, \text{ damage } D_n, \text{ and total strain increment } \Delta \bm{\varepsilon}$ -\State $\text{Compute trial elastic strain } \bm{\varepsilon}^{e,tr} = \bm{\varepsilon}^e_n + \Delta \bm{\varepsilon} \text{ and trial volumetric Jacobian } J^{tr} = \exp(\mathrm{tr}(\bm{\varepsilon}^{e,tr}))$ -\State $\text{Evaluate cold pressure and thermal energy: } p^{c,tr} = p_c(J^{tr}), \quad E_c^{tr} = E_c(J^{tr})$ -\State $\text{Compute trial Kirchhoff stress } \bm{\tau}^{tr} = \frac{\partial \tilde{\Psi}}{\partial \bm{\varepsilon}^{e,tr}} \text{ and yield function } \tilde{F}^{tr}(\bm{\tau}^{tr}, D_n, T_n)$ -\If{$\tilde{F}^{tr} \le 0$} -\State $\bm{\sigma}_{n+1} = (J^{tr})^{-1} \bm{\tau}^{tr}, \quad E_{n+1} = E^{tr}, \quad T_{n+1} = T_n$ -\Return $\text{Step is elastic; accept trial EOS state}$ -\Else -\EndIf -\State $\text{Enforce internal energy balance residual } R_E = E_{n+1} - \tilde{E}(\bm{\varepsilon}^e_{n+1}, D_{n+1}, T_{n+1}) = 0$ -\State $\text{Update Cauchy stress: } \bm{\sigma}_{n+1} = J_{n+1}^{-1} \frac{\partial \tilde{\Psi}}{\partial \bm{\varepsilon}^e_{n+1}}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ temperature } T_{n+1}, \text{ and internal energy } E_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 312-316_ - - -## 4. Known Pitfalls - -- **Decoupling Hydrostatic Pressure EOS from Inelastic Shear Degradation**: Evaluating hydrostatic pressure from an uncoupled EOS while computing shear stress from an independent plastic-damage routine creates thermodynamic inconsistencies, overestimating energy dissipation during dynamic shock loading. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 285, 310)_ -- **Ignoring Pressure Stiffening of Bulk Modulus Under Multi-Gigapascal Compression**: Assuming a constant elastic bulk modulus B_0 under large volumetric shocks miscalculates wave propagation speeds and shock arrival times; pressure-dependent EOS models (e.g., Murnaghan B(p) = B_0 + B_0' p) are required. _(Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 8; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231)_ -- **Unphysical Energy Generation in Uncoupled Thermal Expansion Updates**: Updating temperature and thermal energy independently of mechanical work balance violates the first law of thermodynamics, introducing spurious energy generation during thermo-mechanical return mapping. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 312, 314)_ - -## References - -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/eos-overview.md b/packages/akms/src/akms/_bundled/global_nodes/eos-overview.md deleted file mode 100644 index ea3cb5d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/eos-overview.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -id: eos-overview -title: Equations of State for Solids -domain: computational-mechanics -subdomain: eos -tags: -- eos -- hugoniot -- shock-physics -- high-pressure -- dynamic-loading -status: established -confidence: 0.9 -source: hybrid -edges: -- to: stress-cauchy-kirchhoff - type: feeds-into - weight: 1.0 -- to: eos-mie-gruneisen - type: feeds-into - weight: 1.0 -- to: eos-polynomial - type: feeds-into - weight: 1.0 -- to: damage-spall - type: feeds-into - weight: 0.9 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Equations of State for Solids - -## Summary - -Equations of state (EOS) for solids establish thermodynamic relations between pressure, volumetric strain, internal energy, and temperature, unifying hydrodynamic response with solid strength in finite-strain computational physics. - -## 1. Core Concept - -Equations of State (EOS) for solids govern material behavior under volumetric compression and thermomechanical loading by relating hydrostatic pressure, volumetric Jacobian ratio J = det(F_e), temperature, and internal energy. Traditional shock hydrocodes utilize a combined model approach, evaluating an EOS for pressure and temperature alongside an independent solid mechanics constitutive model for deviatoric stress. However, this decoupling can predict inconsistent pressure values and violate thermodynamic consistency when coupled with damage or pressure-dependent yield. Inelastic Equation of State (IEOS) frameworks resolve these ambiguities by constructing a single unified thermodynamic potential, partitioning Helmholtz free energy or internal energy into cold isotherm compression, thermal lattice vibration, and damage-degraded hyperelastic shear components. - -## 2. Mathematical Formulation - -**Total Stress Volumetric-Deviatoric Decomposition** -$$ -\bm{\sigma} = -p \mathbf{I} + \bm{s}, \quad p = -\frac{1}{3} \mathrm{tr}(\bm{\sigma}) -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 276; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 19_ - -**Unified Inelastic Equation of State Helmholtz Potential** -$$ -\tilde{\Psi}(\bm{\varepsilon}^e, D, T) = \Psi_c(J) + \Psi_l(J, T) + (1 - D) \Psi_{iso}(\bm{\varepsilon}^e_{dev}) -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 309, 310_ - -**Cauchy Stress Tensor Derived from Inelastic Energy Potential** -$$ -\bm{\sigma} = J^{-1} \frac{\partial \tilde{\Psi}(\bm{\varepsilon}^e, D, T)}{\partial \bm{\varepsilon}^e} -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 310, 312_ - -**Pressure-Dependent Bulk Response (Murnaghan Non-Linear Volume Relation)** -$$ -B(p) = B_0 + B_0' p, \quad p(J) = \frac{B_0}{B_0'}\left[ J^{-B_0'} - 1 \right] -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 8; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; p: hydrostatic pressure (-1/3 tr(\bm{\sigma})); \bm{s}: deviatoric Cauchy stress tensor; J: elastic volumetric Jacobian ratio \det(\mathbf{F}^e); \bm{\varepsilon}^e: logarithmic elastic strain tensor; D: scalar damage parameter (0 \le D \le 1); T: absolute temperature; \tilde{\Psi}: unified damage-degraded Helmholtz free energy density; \Psi_c: cold volumetric energy; \Psi_l: thermal lattice energy; \Psi_{iso}: isochoric hyperelastic strain energy density; B(p): pressure-dependent bulk modulus; B_0: initial bulk modulus; B_0': pressure derivative parameter of bulk modulus. - - -## 3. Algorithmic Implementation - -**Unified Inelastic Equation of State (IEOS) Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: elastic deformation gradient } \mathbf{F}^e_n, \text{ internal energy } E_n, \text{ temperature } T_n, \text{ damage } D_n, \text{ and deformation gradient increment } \mathbf{F}$ -\State $\mathbf{F}^e_{tr} = \mathbf{F} \cdot \mathbf{F}^e_n, \quad J_{tr} = \det(\mathbf{F}^e_{tr}), \quad \bm{\varepsilon}^{e,tr} = \frac{1}{2} \ln(\mathbf{F}^e_{tr} \cdot \mathbf{F}^{eT}_{tr})$ -\State $\bm{\tau}^{tr} = \frac{\partial \tilde{\Psi}}{\partial \bm{\varepsilon}^{e,tr}}, \quad \bar{\tau}^{tr} = \sqrt{\frac{3}{2}\bm{s}^{tr}:\bm{s}^{tr}}$ -\State $\tilde{F}^{tr} = \bar{\tau}^{tr} - (1 - D_n) Y(\bar{\varepsilon}_n, T_n)$ -\If{$\tilde{F}^{tr} \le 0$} -\State $\bm{\sigma}_{n+1} = J_{tr}^{-1} \bm{\tau}^{tr}, \quad E_{n+1} = \tilde{E}(\bm{\varepsilon}^{e,tr}, D_n, T_n), \quad T_{n+1} = T_n$ -\Return $\text{Step is elastic; accept trial IEOS state}$ -\Else -\EndIf -\State $\bm{\varepsilon}^e_{n+1} = \bm{\varepsilon}^{e,tr} - \Delta \lambda \mathbf{n}_{n+1}, \quad \bar{\varepsilon}_{n+1} = \bar{\varepsilon}_n + \Delta \lambda$ -\State $\bm{\sigma}_{n+1} = J_{n+1}^{-1} \frac{\partial \tilde{\Psi}(\bm{\varepsilon}^e_{n+1}, D_{n+1}, T_{n+1})}{\partial \bm{\varepsilon}^e_{n+1}}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ temperature } T_{n+1}, \text{ and internal energy } E_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 312-316_ - - -## 4. Known Pitfalls - -- **Thermodynamic Inconsistency in Uncoupled Combined Models**: Evaluating hydrostatic pressure from an independent equation of state (EOS) while computing deviatoric stress from a separate solid mechanics model predicts conflicting pressure values for a given deformation, introducing ad-hoc adjustments that violate energy conservation. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 276, 280)_ -- **Neglecting Pressure Dependency of Bulk Modulus Under High Shock Pressures**: Assuming a constant bulk modulus B_0 under multi-gigapascal dynamic impact causes severe errors in shock wave speed and volumetric deformation; non-linear pressure-dependent volume relations (e.g., Murnaghan EOS B(p) = B_0 + B_0' p) are required. _(Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 8; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231)_ -- **Unphysical Energy Residuals from Decoupling Damage from Thermal Potentials**: Applying scalar damage degradation to solid strength without coupling damage to the thermodynamic stored energy potentials creates unphysical energy generation during finite strain plasticity iterations. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 280, 312-314)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/eos-polynomial.md b/packages/akms/src/akms/_bundled/global_nodes/eos-polynomial.md deleted file mode 100644 index a235f8f..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/eos-polynomial.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: eos-polynomial -title: Polynomial & Tabulated EOS -domain: computational-mechanics -subdomain: eos -tags: -- eos -- polynomial -- sesame -- tabulated -- high-pressure -status: established -confidence: 0.9 -source: hybrid -edges: -- to: eos-overview - type: requires - weight: 1.0 -- to: eos-mie-gruneisen - type: refines - weight: 0.7 -- to: damage-spall - type: feeds-into - weight: 0.8 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Polynomial & Tabulated EOS - -## Summary - -Polynomial and tabulated equation of state (EOS) formulations relate hydrostatic pressure, internal energy, and volumetric deformation through empirical curve-fits, logarithmic strain expansions, or tabular material lookups. - -## 1. Core Concept - -Polynomial and tabulated equations of state (EOS) serve as constitutive models for hydrostatic response under extreme high-pressure dynamic loading. In classical shock hydrocodes, tabular EOS formulations store pre-computed thermodynamic states, interpolating pressure and temperature as functions of density and internal energy. Alternatively, analytic non-linear EOS models represent volumetric stored energy through polynomial expansions in volumetric logarithmic strain or compression measures, such as Murnaghan pressure functions p(J) = (B_0/B_0')(J^{-B_0'} - 1). Within unified Inelastic Equation of State (IEOS) frameworks, tabulated and polynomial cold curves combine with thermal lattice potentials and damage-degraded hyperelastic shear potentials to maintain thermodynamic consistency. - -## 2. Mathematical Formulation - -**Polynomial Volumetric Energy Expansion in Logarithmic Strain** -$$ -W_V(J_E) = \frac{1}{2} B_0 (\ln J_E)^2 \left[ 1 - \frac{1}{3}(B_0' - 2) \ln J_E \right] -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 8_ - -**Non-Linear Murnaghan Pressure-Volume Relation** -$$ -p(J) = \frac{B_0}{B_0'}\left[ J^{-B_0'} - 1 \right] -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 8; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231_ - -**Tabular Internal Energy Potential Coupling in IEOS** -$$ -E(\bm{\varepsilon}^e, D, T) = E_c(J) + E_l(J, T) + (1 - D) \Psi_{iso}(\bm{\varepsilon}^e_{dev}) -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 309, 310_ - -**Cauchy Stress Tensor from Polynomial Energy Potential** -$$ -\bm{\sigma} = J^{-1} \frac{\partial \tilde{\Psi}(\bm{\varepsilon}^e, D, T)}{\partial \bm{\varepsilon}^e} -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 310, 312_ - -**Notation:** -W_V: volumetric elastic strain energy density; B_0: initial bulk modulus; B_0': dimensionless pressure derivative of bulk modulus; J, J_E: elastic volumetric Jacobian ratio \det(\mathbf{F}^e); p: hydrostatic pressure (-1/3 tr(\bm{\sigma})); E: specific internal energy density; E_c(J): cold compression energy function; E_l(J, T): thermal lattice energy function; D: scalar damage parameter; \Psi_{iso}: isochoric hyperelastic strain energy; \bm{\sigma}: Cauchy stress tensor; \bm{\varepsilon}^e: logarithmic elastic strain tensor; \tilde{\Psi}: unified Helmholtz free energy density. - - -## 3. Algorithmic Implementation - -**Polynomial and Tabulated Inelastic Equation of State Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: elastic strain } \bm{\varepsilon}^e_n, \text{ internal energy } E_n, \text{ temperature } T_n, \text{ damage } D_n, \text{ and strain increment } \Delta \bm{\varepsilon}$ -\State $\bm{\varepsilon}^{e,tr} = \bm{\varepsilon}^e_n + \Delta \bm{\varepsilon}, \quad J^{tr} = \exp(\mathrm{tr}(\bm{\varepsilon}^{e,tr}))$ -\If{$\text{Material model uses tabular EOS look-up}$} -\State $p^{c,tr} = \text{TableLookup}(J^{tr}), \quad E_c^{tr} = \text{TableLookup}(J^{tr})$ -\Else -\EndIf -\State $\bm{\tau}^{tr} = \frac{\partial \tilde{\Psi}}{\partial \bm{\varepsilon}^{e,tr}}, \quad \tilde{F}^{tr} = \bar{\tau}^{tr} - (1 - D_n) Y(\bar{\varepsilon}_n, T_n)$ -\If{$\tilde{F}^{tr} \le 0$} -\State $\bm{\sigma}_{n+1} = (J^{tr})^{-1} \bm{\tau}^{tr}, \quad E_{n+1} = E^{tr}, \quad T_{n+1} = T_n$ -\Return $\text{Step is elastic; accept trial state}$ -\Else -\EndIf -\State $\bm{\sigma}_{n+1} = J_{n+1}^{-1} \frac{\partial \tilde{\Psi}(\bm{\varepsilon}^e_{n+1}, D_{n+1}, T_{n+1})}{\partial \bm{\varepsilon}^e_{n+1}}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ internal energy } E_{n+1}, \text{ and temperature } T_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 312-316; Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 8_ - - -## 4. Known Pitfalls - -- **Thermodynamic Discontinuity from Uncoupled Tabular Pressure Modification**: Evaluating hydrostatic pressure from an uncoupled tabular EOS while computing deviatoric stress independently introduces artificial stress modifications that violate thermodynamic energy balance during dynamic plastic deformation. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 276, 280)_ -- **Underpredicting Bulk Stiffening Under Severe Shock Compression**: Truncating polynomial energy expansions to linear terms (constant bulk modulus B_0) underestimates wave speeds and miscalculates shock arrival times under multi-gigapascal compression; non-linear pressure derivatives B_0' are required. _(Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 8; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 231)_ -- **Spurious Energy Residuals in Tabular Temperature Lookups**: Updating temperature from uncoupled tabular EOS routines without enforcing internal energy conservation creates numerical energy residuals during coupled thermo-mechanical return mapping. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 312, 314)_ - -## References - -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/fem-assembly-algorithm.md b/packages/akms/src/akms/_bundled/global_nodes/fem-assembly-algorithm.md deleted file mode 100644 index cded738..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fem-assembly-algorithm.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -id: fem-assembly-algorithm -title: Global Assembly & Sparse Storage -domain: computational-mechanics -subdomain: finite-elements -tags: -- fem -- sparse -- assembly -- linear-algebra -- boundary-conditions -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fem-weak-form-derivation - type: requires - weight: 1.0 -- to: fem-isoparametric-mapping - type: requires - weight: 0.8 -- to: fem-tl-matrix-free-action - type: contradicts - weight: 0.6 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Global Assembly & Sparse Storage - -## Summary - -Global finite element assembly synthesizes element-level stiffness matrices and force vectors into global discrete linear or non-linear algebraic systems using element connectivity mapping arrays. The assembled global stiffness matrix is stored in sparse compressed formats or preallocated coordinate arrays, and essential boundary conditions are enforced either through symmetric submatrix partitioning or element-level elimination. - -## 1. Core Concept - -In finite element analysis, continuous weak forms are evaluated as sums of local integrals over individual element domains. Global assembly accumulates local element stiffness matrices and nodal force vectors into the global algebraic system using a local-to-global degree-of-freedom mapping. Because basis functions have local compact support, global stiffness matrices are highly sparse and banded. In multi-threaded parallel assembly, data race conditions are avoided by cell coloring or preallocated coordinate assembly. Essential Dirichlet boundary conditions are applied via submatrix partitioning or symmetric partial Gaussian elimination to preserve matrix properties for linear solvers. - -## 2. Mathematical Formulation - -**Global Stiffness Matrix Assembly** -$$ -K = \sum_{e=1}^{n_e} (L^e)^T K_e L^e = \sum_{e=1}^{n_e} Z_e^T \left( \int_{V_e} B^T D B \, \mathrm{d}V \right) Z_e -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 2.5, Eq. 2.5.9, p. 42; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.2, Eq. 2.43, p. 44_ - -**Global Nodal Internal Force Vector Assembly** -$$ -f^{\mathrm{int}} = \sum_{e=1}^{n_e} (L^e)^T f_e^{\mathrm{int}} = \sum_{e=1}^{n_e} Z_e^T \int_{V_e} B^T \sigma \, \mathrm{d}V -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 2.5, Eq. 2.5.5, p. 41; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.2, Eq. 2.18, p. 35_ - -**Local-to-Global Multi-Index Tensor Assembly** -$$ -A_I = \sum_{T \in \mathcal{T}_I} A_{T, \iota_T^{-1}(I)} -$$ -_Source: FE_Assembly.pdf, Sec. 6.1, Eq. 6.5, p. 142_ - -**Essential Boundary Condition Partitioning** -$$ -K_{ff} a_f = f^{\mathrm{ext},f} - K_{fp} a_p -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.3, Eq. 2.60, p. 59; ME280A.pdf, Sec. 6.2, Eq. 6.27, p. 146_ - -**Notation:** -{'K': 'Assembled global stiffness matrix.', 'K_e': 'Local element stiffness matrix.', 'f^{\\mathrm{int}}': 'Assembled global internal nodal force vector.', 'f_e^{\\mathrm{int}}': 'Local element internal nodal force vector.', 'L^e, Z_e': 'Boolean element connectivity matrix (gather/scatter operator).', '\\iota_T': 'Local-to-global degree-of-freedom mapping function.', 'a_f': 'Vector of unknown displacements at unconstrained (free) degrees of freedom.', 'a_p': 'Vector of prescribed displacements at constrained degrees of freedom.'} - - -## 3. Algorithmic Implementation - -**Standard Finite Element Scatter Assembly Algorithm** -$$ -\begin{algorithmic} -\State $Initialize global stiffness matrix K \gets 0 and global force vector f^{\mathrm{int}} \gets 0$ -\For{$e \gets 1 \text{ to } n_e$} -\State $Extract element degree-of-freedom map d_e \gets \mathrm{dofmap}(e)$ -\State $Compute element stiffness matrix K_e = \int_{V_e} B^T D B \, \mathrm{d}V \text{ and force } f_e^{\mathrm{int}} = \int_{V_e} B^T \sigma \, \mathrm{d}V$ -\For{$i \gets 1 \text{ to } n_{\mathrm{dof},e}$} -\State $I \gets d_e[i]$ -\State $f^{\mathrm{int}}[I] \gets f^{\mathrm{int}}[I] + f_e^{\mathrm{int}}[i]$ -\For{$j \gets 1 \text{ to } n_{\mathrm{dof},e}$} -\State $J \gets d_e[j]$ -\State $K[I, J] \gets K[I, J] + K_e[i, j]$ -\EndFor -\EndFor -\EndFor -\Return $K, f^{\mathrm{int}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: FE_Assembly.pdf, Sec. 6.1, Alg. 2, p. 142; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.3, p. 58_ - - -## 4. Known Pitfalls - -- **Uninitialized Sparse Matrix Sparsity Pattern**: Inserting element matrix entries into an uninitialized compressed sparse row (CRS/CSR) matrix data structure without precalculating the non-zero sparsity pattern incurs severe memory reallocation and search overhead. Mitigation: Compute and preallocate the global sparsity pattern from element connectivity maps before assembly. _(Source: FE_Assembly.pdf, Sec. 6.2, p. 143; Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \(p\)-Multigrid.pdf, Sec. III-D, p. 7)_ -- **Shared-Memory Race Conditions in Parallel Assembly**: In multi-threaded parallel assembly, multiple threads attempting to write local element contributions simultaneously into shared global matrix entries for boundary or shared nodes cause data race corruption. Mitigation: Apply mesh/cell coloring algorithms so that no two elements assembled concurrently share common global nodes, or use race-free preallocated coordinate assembly. _(Source: FE_Assembly.pdf, Sec. 6.4, p. 145; Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \(p\)-Multigrid.pdf, Sec. III-D, pp. 6–7)_ -- **Loss of Matrix Symmetry Under Naive Boundary Condition Imposition**: Directly overwriting rows and columns of prescribed degrees of freedom in assembled global stiffness matrices without symmetric row-column reduction or element-level elimination destroys matrix symmetry, preventing the use of symmetric iterative solvers like Conjugate Gradient. Mitigation: Apply symmetric partial Gaussian elimination at the element level prior to assembly, or perform explicit submatrix partitioning K_{ff} a_f = f_f - K_{fp} a_p. _(Source: FE_Assembly.pdf, Sec. 6.3, pp. 144–145; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.3, p. 59)_ - -## References - -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \(p\)-Multigrid.pdf -- FE_Assembly.pdf -- ME280A.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/fem-hourglass-control.md b/packages/akms/src/akms/_bundled/global_nodes/fem-hourglass-control.md deleted file mode 100644 index e238ff0..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fem-hourglass-control.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: fem-hourglass-control -title: Hourglass Stabilization -domain: computational-mechanics -subdomain: finite-elements -tags: -- fem -- hourglass -- reduced-integration -- stabilization -- flanagan-belytschko -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fem-isoparametric-mapping - type: requires - weight: 0.9 -- to: fem-locking-remedies - type: requires - weight: 0.9 -- to: kinematics-velocity-gradient - type: feeds-into - weight: 0.6 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Hourglass Stabilization - -## Summary - -Hourglass stabilization suppresses spurious zero-energy deformation modes (hourglass modes) that arise when under-integrated (one-point quadrature) continuum elements are used in finite element analyses. Stabilization methods add artificial stiffness or viscosity orthogonal to physical rigid-body and linear strain fields using hourglass vectors, scaling parameters, and dilatational wave speeds. - -## 1. Core Concept - -Under-integrated isoparametric elements, such as 4-node quadrilaterals or 8-node hexahedra with one-point quadrature, eliminate volumetric locking and significantly reduce computational effort. However, reduced integration creates rank-deficient stiffness matrices with spurious non-zero kinematic modes that produce zero strain at the quadrature center. Hourglass control eliminates these spurious modes by projecting nodal velocity/displacement vectors onto specialized hourglass vectors orthogonal to linear fields, adding a stabilization force scaled by a perturbation stiffness modulus C^Q or maximum element stiffness K_{\mathrm{max}}. - -## 2. Mathematical Formulation - -**Hourglass Vector Orthogonality** -$$ -\gamma = h - \frac{1}{A} (h^T x) b_1 - \frac{1}{A} (h^T y) b_2 -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 8.7.2, Eq. 8.7.4, p. 519_ - -**Generalized Hourglass Strain Rate** -$$ -q_i = \gamma^T v_i -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 8.7.3, Eq. 8.7.9b, p. 521_ - -**Perturbation Hourglass Stiffness Modulus** -$$ -C^Q = \frac{1}{2} \alpha_s c^2 \rho A b_i^T b_i -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 8.7.3, Eq. 8.7.14, p. 522_ - -**Hourglass Stabilization Nodal Force** -$$ -f_i^{\mathrm{stab}} = Q_i \gamma -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 8.7.3, Eq. 8.7.11 & 8.7.18, pp. 521–523_ - -**Hexahedron Hourglass Resistance Force** -$$ -f_{Ii}^{\mathrm{Hg}} = k u_{Ji} \gamma_J \gamma_I, \quad k = \frac{\epsilon K_{\mathrm{max}}}{8} -$$ -_Source: TL_hourglass.pdf, Eqs. 4, 12, 13, pp. 1315–1316_ - -**Notation:** -{'\\gamma': 'Hourglass projection vector orthogonal to linear displacement fields.', 'h': 'Base hourglass vector [1, -1, 1, -1]^T.', 'q_i': 'Generalized hourglass strain rate.', 'Q_i': 'Generalized hourglass stress.', 'C^Q': 'Perturbation hourglass stabilization modulus.', 'c': 'Dilatational wave speed c = \\sqrt{(\\lambda + 2\\mu)/\\rho}.', '\\alpha_s': 'Non-dimensional hourglass scaling parameter (\\alpha_s \\approx 0.1).', 'f_i^{\\mathrm{stab}}': 'Vector of stabilization nodal forces.'} - - -## 3. Algorithmic Implementation - -**Perturbation Hourglass Stabilization Force Computation** -$$ -\begin{algorithmic} -\State $Given nodal coordinates x, y, nodal velocities v_x, v_y, and material properties \rho, c, \alpha_s$ -\State $Compute element area A and shape function derivatives b_1, b_2 at element centroid \xi = (0,0)$ -\State $Compute hourglass vector \gamma \gets h - \frac{1}{A}(h^T x) b_1 - \frac{1}{A}(h^T y) b_2$ -\State $Compute generalized strain rates q_x \gets \gamma^T v_x \text{ and } q_y \gets \gamma^T v_y$ -\State $Compute stabilization modulus C^Q \gets \frac{1}{2} \alpha_s c^2 \rho A (b_1^T b_1 + b_2^T b_2)$ -\State $Compute generalized stress rates \dot{Q}_x \gets C^Q q_x \text{ and } \dot{Q}_y \gets C^Q q_y$ -\State $Update generalized stresses Q_x \gets Q_x + \Delta t \dot{Q}_x \text{ and } Q_y \gets Q_y + \Delta t \dot{Q}_y$ -\State $Compute stabilization nodal forces f_x^{\mathrm{stab}} \gets Q_x \gamma \text{ and } f_y^{\mathrm{stab}} \gets Q_y \gamma$ -\Return $f_x^{\mathrm{stab}}, f_y^{\mathrm{stab}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 8.7.3 & Box 8.2, pp. 521–524_ - - -## 4. Known Pitfalls - -- **Over-Stabilization and Artificial Stiffening**: Setting the hourglass scaling parameter \alpha_s or \epsilon too large introduces excessive artificial stiffness into the model, locking the element in bending or shear and corrupting the physical response. Mitigation: Keep scaling parameters in recommended ranges (\alpha_s \approx 0.1, or \epsilon between 0.01 and 0.05). _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 8.7.5, p. 522 & Sec. 9.9, p. 593)_ -- **Non-Orthogonality Under Finite Rigid-Body Rotations**: Evaluating hourglass vectors in the unrotated global coordinate frame causes rigid-body rotations to generate non-zero fake hourglass strain rates q_i, producing spurious internal stabilization forces. Mitigation: Evaluate hourglass vectors and nodal velocities in a corotational or objective local element coordinate frame. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 8.2, p. 524; TL_hourglass.pdf, Sec. 1, p. 1315)_ - -## References - -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- TL_hourglass.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/fem-isoparametric-mapping.md b/packages/akms/src/akms/_bundled/global_nodes/fem-isoparametric-mapping.md deleted file mode 100644 index 4920023..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fem-isoparametric-mapping.md +++ /dev/null @@ -1,244 +0,0 @@ ---- -id: fem-isoparametric-mapping -title: Isoparametric Mapping & Numerical Integration -domain: computational-mechanics -subdomain: finite-elements -tags: -- fem -- isoparametric -- quadrature -- gauss-legendre -- elements -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fem-shape-functions - type: requires - weight: 1.0 - note: Same shape functions used for geometry mapping and field interpolation -- to: fem-weak-form-derivation - type: feeds-into - weight: 1.0 - note: Weak-form integrals are evaluated by Gauss quadrature on the parent element -- to: fem-tl-b-matrix - type: feeds-into - weight: 1.0 - note: B-matrix uses the chain-rule Jacobian to map parent gradients to physical gradients -- to: fem-locking-remedies - type: feeds-into - weight: 0.8 - note: Reduced integration is one source of locking remedies but introduces hourglass modes -context_size: medium -reading_priority: full -load_with: -- fem-shape-functions -content_ref: null -akms_schema: v2 ---- - -# Isoparametric Mapping & Numerical Integration - -## Summary -The isoparametric concept uses identical shape functions for geometric mapping and field interpolation, allowing curved / distorted physical elements to be parameterised by a single fixed parent element $[-1,1]^d$. Physical coordinates are interpolated as $\mathbf{x}(\boldsymbol{\xi})=\sum_a N_a(\boldsymbol{\xi})\mathbf{x}_a$ and field values as $u(\boldsymbol{\xi})=\sum_a N_a(\boldsymbol{\xi})u_a$. The parametric Jacobian $\mathbf{J}=\partial\mathbf{x}/\partial\boldsymbol{\xi}$ controls the chain rule $\partial N_a/\partial\mathbf{x}=\mathbf{J}^{-1}\,\partial N_a/\partial\boldsymbol{\xi}$ and the volume element $dV=\det\mathbf{J}\,d\xi^1 d\xi^2 d\xi^3$. Numerical integration uses tensor-product Gauss-Legendre quadrature: an $n$-point rule integrates polynomials up to degree $2n-1$ exactly. Full integration ($n_g=$ poly order) ensures correct stiffness; reduced integration saves cost but introduces zero-energy hourglass modes that need stabilisation. Distorted elements with $\det\mathbf{J}\le 0$ render the mapping invalid. - - -## 1. Core Concept -Mapping curved physical elements onto a regular parent element is the workhorse of practical FEM. The isoparametric concept makes the mapping use the SAME shape functions as the field interpolation, which guarantees that a constant field is reproduced exactly (the patch test) and that geometric continuity matches displacement continuity at element boundaries. The cost is a Jacobian $\mathbf{J}=\partial\mathbf{x}/\partial\boldsymbol{\xi}$ that varies in space and must be inverted at every Gauss point: physical gradients of shape functions are obtained via the chain rule $\partial N_a/\partial\mathbf{x}=\mathbf{J}^{-1}\partial N_a/\partial\boldsymbol{\xi}$, and the volume element picks up a $\det\mathbf{J}$ factor. Numerical integration on the parent uses Gauss-Legendre quadrature, which is exact for polynomials up to degree $2n-1$ with $n$ points per dimension — sufficient for the stiffness integrand $\mathbb{C}_{ikjl}(\partial N_a/\partial x_k)(\partial N_b/\partial x_l)$ when $n_g\ge p$ (polynomial degree of shape functions). Reduced integration ($n_g0$ required for valid mapping - -**Chain rule for physical gradients:** - -$$ -\frac{\partial N_a}{\partial \mathbf{x}} = \mathbf{J}^{-1}\,\frac{\partial N_a}{\partial \boldsymbol{\xi}},\qquad -\frac{\partial N_a}{\partial x_i} = \sum_{j=1}^{d}(\mathbf{J}^{-1})_{ij}\,(\partial N_a/\partial \xi_j) -$$ - -where Standard chain rule on a smooth invertible map - -**Volume element and integration:** - -$$ -dV = \det\mathbf{J}\,d\xi^1\,d\xi^2\,d\xi^3,\qquad -\int_{\Omega_e} f(\mathbf{x})\,dV = \int_{\hat\Omega} f(\mathbf{x}(\boldsymbol{\xi}))\,\det\mathbf{J}\,d\boldsymbol{\xi} -$$ - -where Pull-back of the integral onto the parent element - -**Gauss-Legendre tensor-product quadrature:** - -$$ -\int_{\hat\Omega} g(\boldsymbol{\xi})\,d\boldsymbol{\xi} -\approx \sum_{g_1=1}^{n_g}\sum_{g_2=1}^{n_g}\sum_{g_3=1}^{n_g} - w_{g_1}w_{g_2}w_{g_3}\,g(\xi_{g_1},\xi_{g_2},\xi_{g_3}) -$$ - -where Exact for polynomials up to degree $2n_g-1$ per dimension - -**Standard Gauss points and weights (1D, $n_g=2$):** - -$$ -\xi_1 = -1/\sqrt{3},\;\xi_2 = +1/\sqrt{3},\qquad -w_1 = w_2 = 1 -$$ - -where Two-point rule integrates cubics exactly; standard for hex8 elements - -**Full vs reduced integration:** - -$$ -\text{Full} \colon n_g = p + 1 \;\text{(}p\text{ poly degree)} \;\Rightarrow\; \text{stiffness exact},\\ -\text{Reduced} \colon n_g = p \;\Rightarrow\; \text{cheaper, may produce hourglass modes} -$$ - -where Full integration removes spurious zero-energy modes; reduced integration trades cost for locking relief - -**Element internal force / stiffness via quadrature:** - -$$ -K_{ab,ij}^e = \sum_{g}\,(\partial N_a/\partial x_k)\,\mathbb{C}_{ikjl}\,(\partial N_b/\partial x_l)\, - \det\mathbf{J}(\boldsymbol{\xi}_g)\,w_g -$$ - -where Element-level assembly via Gauss quadrature - -**Distorted-element criterion:** - -$$ -\det\mathbf{J}(\boldsymbol{\xi}_g) > J_{\min}\,(\sim 10^{-3}\,\max\det\mathbf{J}) -$$ - -where Validate at every Gauss point; very small $\det\mathbf{J}$ indicates a distorted / inverted element - -**Notation:** - -- $\boldsymbol{\xi}$ — Parametric (parent) coordinates -- $\mathbf{x}$ — Physical coordinates -- $\hat\Omega = [-1,1]^d$ — Parent (master) element -- $\Omega_e$ — Physical element -- $\mathbf{J}$ — Parametric Jacobian, $\partial\mathbf{x}/\partial\boldsymbol{\xi}$ -- $N_a(\boldsymbol{\xi})$ — Shape function for local node $a$ -- $n_n$ — Nodes per element -- $n_g$ — Gauss points per dimension -- $w_g$ — Gauss quadrature weight -- $p$ — Polynomial degree of shape functions - - -## 3. Algorithmic Implementation -**Algorithm: Compute Element Quadrature Data (one-time setup)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \text{element nodes } \{\mathbf{x}_a\},\,\text{Gauss data } \{(\boldsymbol{\xi}_g, w_g)\}$ -\For{$\text{each Gauss point } g$} -\For{$a = 1,\ldots,n_n,\,k = 1,\ldots,d$} -\State $(\partial N_a/\partial \xi_k)|_g \gets \text{evaluate at } \boldsymbol{\xi}_g$ -\EndFor -\State $\mathbf{J}_g \gets \sum_a \mathbf{x}_a \otimes (\partial N_a/\partial \boldsymbol{\xi})|_g$ -\State $\det\mathbf{J}_g \gets \det(\mathbf{J}_g)$ -\If{$\det\mathbf{J}_g \le J_{\min}$} -\State $\text{abort: distorted / inverted element}$ -\EndIf -\State $\mathbf{J}_g^{-1} \gets \mathrm{cofactor\;inverse}(\mathbf{J}_g)$ -\For{$a = 1,\ldots,n_n$} -\State $(\partial N_a/\partial \mathbf{x})|_g \gets \mathbf{J}_g^{-1}\,(\partial N_a/\partial \boldsymbol{\xi})|_g$ -\EndFor -\EndFor -\Return $\{(\partial N_a/\partial \mathbf{x})|_g,\,\det\mathbf{J}_g\,w_g\}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Pre-compute once per element at the START of the simulation (TL-FEM uses reference geometry, never changes). Store $(\partial N_a/\partial \mathbf{x})|_g$ in a `ti.field(dtype=ti.f64, shape=(n_elem, n_GP, n_n, d))` and $\det\mathbf{J}_g\,w_g$ in `ti.field(shape=(n_elem, n_GP))`. Per-element cost: one $3\times 3$ inverse + chain-rule per Gauss point = ~$30 n_g$ FMAs. Validate $\det\mathbf{J}>J_{\min}$ on every element at startup; any failure indicates mesh-quality issue. - - -**Algorithm: Gauss-Legendre Quadrature on a Parent Cube** - -$$ -\begin{algorithmic} -\State $\text{input} \colon n_g \;\text{(points per dim)},\,\text{integrand handle } f(\boldsymbol{\xi})$ -\State $(\xi^{1D}_g, w^{1D}_g)_{g=1}^{n_g} \gets \text{Gauss-Legendre tabulated values}$ -\State $I \gets 0$ -\For{$g_1, g_2, g_3 = 1,\ldots,n_g$} -\State $w_g \gets w^{1D}_{g_1}\,w^{1D}_{g_2}\,w^{1D}_{g_3}$ -\State $\boldsymbol{\xi}_g \gets (\xi^{1D}_{g_1},\xi^{1D}_{g_2},\xi^{1D}_{g_3})$ -\State $I \mathrel{+}= w_g\,f(\boldsymbol{\xi}_g)$ -\EndFor -\Return $I$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Hard-code Gauss-Legendre points / weights for the most common rules ($n_g=1,2,3$). For hex8 use $2\times 2\times 2=8$ Gauss points (full integration); reduced is $1\times 1\times 1=1$. Tensor-product structure means the inner loops can be unrolled with `ti.static`; the integrand call is the dominant cost. - - -**Algorithm: Patch-Test Verification** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \text{distorted element mesh},\,\text{linear constant-strain trial field}$ -\State $\text{prescribe } \mathbf{u}|_{\partial\Omega} = \boldsymbol{\varepsilon}_0\,\mathbf{x}$ -\State $\text{solve and recover } \boldsymbol{\sigma}_h\,\text{at all Gauss points}$ -\State $\text{check } \|\boldsymbol{\sigma}_h - \mathbb{C}\colon\boldsymbol{\varepsilon}_0\| < \tau\,(\sim 10^{-12})$ -\Return $\text{pass / fail}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Standard verification benchmark every isoparametric implementation must pass. Failure indicates incorrect Jacobian inversion, missing $\det\mathbf{J}$ in the volume element, or wrong Gauss point locations. Run on a 2x2x2 mesh with one warped interior element; uniform extension must produce uniform stress to round-off. - - - -## 4. Known Pitfalls -**Distorted elements with $\det\mathbf{J}\le 0$:** A distorted physical element with re-entrant corners or extreme aspect ratio can yield $\det\mathbf{J}_g\to 0$ or even $<0$ at some Gauss points — the mapping is then non-invertible. Detect $\det\mathbf{J} \mathrm{tol}$} -\State $Solve linear system K \Delta a \gets r$ -\State $Update displacement vector a \gets a + \Delta a$ -\State $Re-evaluate K \gets \mathrm{assembleStiffness}(a) \text{ and } f^{\mathrm{int}} \gets \mathrm{assembleInternalForce}(a)$ -\State $Recompute residual vector r \gets f^{\mathrm{ext}} - f^{\mathrm{int}}$ -\EndWhile -\EndFor -\Return $a$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.4, pp. 46–48 & Sec. 3.2, p. 80; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 6.4, p. 345 & Box 6.6, p. 375_ - - -## 4. Known Pitfalls - -- **Divergence at Limit Points and Snap-Through**: Standard load-controlled Newton-Raphson iteration fails to converge near limit points or snap-through instabilities where the tangent stiffness matrix K becomes singular or ill-conditioned. Mitigation: Switch from load control to displacement control or path-following arc-length methods (such as Riks' technique) to navigate past limit points. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.5, pp. 50–53 & Sec. 4.2, pp. 116–118)_ -- **Inconsistent Tangent Operator Causing Loss of Quadratic Convergence**: Using a continuum elastic-plastic tangent matrix instead of the algorithmic consistent tangent matrix derived from the implicit return mapping algorithm reduces the asymptotic convergence rate of the global Newton-Raphson loop from quadratic to linear. Mitigation: Compute and assemble the algorithmic consistent tangent modulus C^{\mathrm{alg}} corresponding exactly to the discrete stress update scheme. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 6.6, p. 375; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 7.5, p. 251 & Box 7.7, p. 252)_ - -## References - -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \(p\)-Multigrid.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/fem-shape-functions.md b/packages/akms/src/akms/_bundled/global_nodes/fem-shape-functions.md deleted file mode 100644 index 0e3cc4a..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fem-shape-functions.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: fem-shape-functions -title: Shape Function Families -domain: computational-mechanics -subdomain: finite-elements -tags: -- fem -- shape-functions -- lagrange -- serendipity -- elements -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fem-isoparametric-mapping - type: feeds-into - weight: 1.0 -- to: fem-weak-form-derivation - type: feeds-into - weight: 1.0 -- to: fem-tl-b-matrix - type: feeds-into - weight: 0.9 -- to: fem-mixed-methods - type: refines - weight: 0.6 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Shape Function Families - -## Summary - -Shape functions interpolate spatial coordinates and field variables across finite element domains from discrete nodal degrees of freedom. Shape function families include standard Lagrangian polynomials, serendipity boundary-node formulations, hierarchical p-version extensions, and B-spline/NURBS basis functions in isogeometric analysis. All valid shape function families satisfy partition of unity and interpolation conditions to guarantee rigid-body representation and convergence. - -## 1. Core Concept - -Finite element spatial discretizations construct continuous trial and test function spaces using piecewise polynomial shape functions defined on a master/parent element domain. Lagrangian shape functions use tensor products of 1D Lagrange polynomials passing through all grid nodes, including interior points. Serendipity shape functions eliminate internal nodes by placing degrees of freedom exclusively along element boundaries. Hierarchical shape functions add higher-order polynomial modes onto existing lower-order nodal modes without altering lower-order functions, simplifying p-refinement. All valid shape function sets satisfy the partition of unity condition \sum_I N_I(\boldsymbol{\xi}) = 1, ensuring exact representation of rigid-body translations and passing the patch test. - -## 2. Mathematical Formulation - -**Partition of Unity Condition** -$$ -\sum_{I=1}^{n_{\mathrm{en}}} N_I(\boldsymbol{\xi}) = 1 -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 11.2, Eq. 11.2.1, p. 647; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.2, p. 33_ - -**Bilinear Quadrilateral (Quad4) Shape Functions** -$$ -N_I(\xi, \eta) = \frac{1}{4} (1 + \xi_I \xi)(1 + \eta_I \eta), \quad I \in \{1, 2, 3, 4\} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.3, p. 40; ME280A.pdf, Sec. 5.36, p. 124_ - -**Trilinear Hexahedral (Hexa8) Shape Functions** -$$ -N_I(\xi, \eta, \zeta) = \frac{1}{8} (1 + \xi_I \xi)(1 + \eta_I \eta)(1 + \zeta_I \zeta), \quad I \in \{1, \dots, 8\} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.2, Box 2.2, p. 36; ME280A.pdf, Sec. 5.36, Eq. 5.103, p. 132_ - -**One-Dimensional Hierarchical Shape Functions** -$$ -N_1(\xi) = \frac{1}{2}(1 - \xi), \quad N_2(\xi) = \frac{1}{2}(1 + \xi), \quad N_c(\xi) = 1 - \xi^2 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 9.1, Eq. 9.14a, p. 310; ME280A.pdf, Sec. 5.7, p. 133_ - -**Notation:** -{'N_I': 'Interpolation shape function associated with node I.', '\\xi, \\eta, \\zeta': 'Parametric coordinates in parent element domain.', 'u_I': 'Vector or scalar degree of freedom at node I.', 'n_{\\mathrm{en}}': 'Number of element nodes / basis functions.'} - - -## 3. Algorithmic Implementation - -**Bilinear Quadrilateral Shape Function and Derivative Evaluation** -$$ -\begin{algorithmic} -\State $Given parent coordinates \boldsymbol{\xi} = (\xi, \eta)$ -\State $Evaluate N_1 \gets \frac{1}{4}(1-\xi)(1-\eta), \quad N_2 \gets \frac{1}{4}(1+\xi)(1-\eta)$ -\State $Evaluate N_3 \gets \frac{1}{4}(1+\xi)(1+\eta), \quad N_4 \gets \frac{1}{4}(1-\xi)(1+\eta)$ -\State $Compute parametric derivatives \frac{\partial N_1}{\partial \boldsymbol{\xi}} \gets \begin{pmatrix} -\frac{1}{4}(1-\eta) \\ -\frac{1}{4}(1-\xi) \end{pmatrix}, \quad \frac{\partial N_2}{\partial \boldsymbol{\xi}} \gets \begin{pmatrix} \frac{1}{4}(1-\eta) \\ -\frac{1}{4}(1+\xi) \end{pmatrix}$ -\State $Compute parametric derivatives \frac{\partial N_3}{\partial \boldsymbol{\xi}} \gets \begin{pmatrix} \frac{1}{4}(1+\eta) \\ \frac{1}{4}(1+\xi) \end{pmatrix}, \quad \frac{\partial N_4}{\partial \boldsymbol{\xi}} \gets \begin{pmatrix} -\frac{1}{4}(1+\eta) \\ \frac{1}{4}(1-\xi) \end{pmatrix}$ -\Return $N, \frac{\partial N}{\partial \boldsymbol{\xi}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.3, p. 40; ME280A.pdf, Sec. 5.36, p. 124_ - - -## 4. Known Pitfalls - -- **Violation of Partition of Unity in Incomplete Bases**: Constructing custom polynomial shape function sets without verifying that \sum_I N_I(\boldsymbol{\xi}) = 1 prevents the element from representing constant field translation, failing the patch test and causing convergence failure under mesh refinement. Mitigation: Ensure shape function derivations enforce partition of unity across the entire element domain. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 8.3, p. 488 & Sec. 11.2, p. 647; ME280A.pdf, Sec. 5.36, p. 128)_ -- **Incompatible Inter-Element Continuity in Higher-Order Serendipity Elements**: Mixing serendipity elements with different polynomial orders or distorted element geometries can cause displacement field discontinuities across element boundaries because boundary edge interpolations fail to match. Mitigation: Ensure matching node configurations along shared interfaces or use isoparametric mappings with compatible boundary interpolations. _(Source: ME280A.pdf, Sec. 5.7, Problem 6, p. 134; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 7.6, p. 275)_ - -## References - -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- ME280A.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/fem-tl-b-matrix.md b/packages/akms/src/akms/_bundled/global_nodes/fem-tl-b-matrix.md deleted file mode 100644 index ba293ca..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fem-tl-b-matrix.md +++ /dev/null @@ -1,239 +0,0 @@ ---- -id: fem-tl-b-matrix -title: TL B-Matrix (Strain-Displacement Operator) -domain: computational-mechanics -subdomain: finite-elements -tags: -- fem -- finite-strain -- total-lagrangian -- b-matrix -- elements -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fem-tl-weak-form - type: requires - weight: 1.0 - note: B-matrix is the operator linking nodal $\delta\mathbf{u}$ to $\delta\mathbf{E}$ in the weak form -- to: kinematics-motion-deformation-gradient - type: requires - weight: 1.0 - note: $\mathbf{B}_1$ depends on $\mathbf{F}$ — nonlinear in displacement -- to: tensor-voigt-notation - type: requires - weight: 0.8 - note: Voigt form of B-matrix uses the kinematic rule (factor 2 on shears) -- to: fem-tl-linearization - type: feeds-into - weight: 1.0 - note: Material tangent $\mathbf{K}_m=\int\mathbf{B}^T\mathbb{C}^{SE}\mathbf{B}\,dV_0$ -- to: kinematics-convected-coordinates - type: refines - weight: 0.5 - note: Convected-basis B-matrix is an alternative formulation in curvilinear coordinates -context_size: large -reading_priority: full -load_with: -- fem-tl-weak-form -- tensor-voigt-notation -content_ref: null -akms_schema: v2 ---- - -# TL B-Matrix (Strain-Displacement Operator) - -## Summary -The TL B-matrix maps nodal displacement variations to the variation of Green-Lagrange strain: $\delta\mathbf{E}=\sum_a\mathbf{B}_a\,\delta\mathbf{u}_a$. It splits into a constant linear part $\mathbf{B}_0$ (the small-strain B-matrix) and a displacement-dependent nonlinear part $\mathbf{B}_1(\mathbf{u})=\mathbf{B}_1(\mathbf{F})$. In Voigt / kinematic form (with factor 2 on shears), the indicial pieces are $(\mathbf{B}_0)_{aIJk}=\tfrac12(\delta_{kI}\partial N_a/\partial X_J+\delta_{kJ}\partial N_a/\partial X_I)$ and $(\mathbf{B}_1)_{aIJk}=\tfrac12(F_{kI}\partial N_a/\partial X_J+F_{kJ}\partial N_a/\partial X_I)-(\mathbf{B}_0)_{aIJk}$, so the full B-matrix is $\mathbf{B}_a=\mathbf{B}_0(\mathbf{F}=\mathbf{I})+\mathbf{B}_1(\mathbf{F})=\tfrac12(F_{kI}\partial N_a/\partial X_J+F_{kJ}\partial N_a/\partial X_I)$ in compact form. Reference shape function gradients $\partial N_a/\partial\mathbf{X}$ are constant in time (TL); only $\mathbf{F}$ updates each step. The internal-force computation $\int_{\Omega_0}\mathbf{B}^T\mathbf{S}\,dV_0$ contracts the B-matrix with the PK2 stress at every Gauss point. - - -## 1. Core Concept -The TL B-matrix is the algebraic backbone of finite-strain FEM assembly: it converts the geometric question "how does the strain change when nodal displacements change?" into a linear operator on the nodal displacement increments. The split $\mathbf{B}=\mathbf{B}_0+\mathbf{B}_1(\mathbf{u})$ separates the (cheap, constant) small-strain contribution from the (expensive, $\mathbf{F}$-dependent) finite-strain contribution. $\mathbf{B}_0$ alone gives the linear elasticity B-matrix and is recovered when $\mathbf{F}\to\mathbf{I}$; $\mathbf{B}_1$ adds the cubic / quadratic terms in displacement that make the residual nonlinear. Reference shape function gradients $\partial N_a/\partial\mathbf{X}$ — the data that enters both $\mathbf{B}_0$ and $\mathbf{B}_1$ — are computed once at the start of the simulation from the reference parent-physical mapping and stored: a major efficiency advantage over UL-FEM, where current shape function gradients $\partial N_a/\partial\mathbf{x}=(\partial N_a/\partial\mathbf{X})\mathbf{F}^{-1}$ must be recomputed every step. The Voigt convention introduces the most common bug: the kinematic rule (factor 2 on shears) on the strain side is what makes $\mathbf{B}^T\{\mathbf{S}\}$ produce the correct internal force. - - -## 2. Mathematical Formulation -Indices $a$ runs over element nodes ($n_n$ total), $i,j,k\in\{1,2,3\}$ spatial, $I,J,K\in\{1,2,3\}$ material. $\nabla_0 N_a=\partial N_a/\partial\mathbf{X}$. $\mathbf{F}=\mathbf{I}+\sum_a\mathbf{u}_a\otimes\nabla_0 N_a$. - - -**Nodal strain-displacement relation:** - -$$ -\delta\mathbf{E}(\mathbf{X}) = \sum_{a=1}^{n_n}\mathbf{B}_a(\mathbf{X};\mathbf{F})\,\delta\mathbf{u}_a -$$ - -where Linear in $\delta\mathbf{u}_a$, nonlinear in $\mathbf{u}_a$ through $\mathbf{F}$ - -**Tensor (indicial) form of TL B-matrix:** - -$$ -(\mathbf{B}_a)_{IJk} = \tfrac{1}{2}\!\left(F_{kI}\,\frac{\partial N_a}{\partial X_J} + F_{kJ}\,\frac{\partial N_a}{\partial X_I}\right) -$$ - -where Symmetric in $(I,J)$; the $k$-leg is spatial / displacement-component - -**Linear / nonlinear split:** - -$$ -\mathbf{B}_a = \mathbf{B}_0^a + \mathbf{B}_1^a(\mathbf{F}),\qquad -(\mathbf{B}_0^a)_{IJk} = \tfrac{1}{2}(\delta_{kI}\,\partial N_a/\partial X_J + \delta_{kJ}\,\partial N_a/\partial X_I),\quad -(\mathbf{B}_1^a)_{IJk} = (\mathbf{B}_a)_{IJk} - (\mathbf{B}_0^a)_{IJk} -$$ - -where $\mathbf{B}_0$ is the small-strain B-matrix; $\mathbf{B}_1$ vanishes when $\mathbf{F}=\mathbf{I}$ - -**Voigt form (3D, kinematic rule):** - -$$ -[\mathbf{B}_a]_{6\times 3} -= \begin{bmatrix} -F_{1I}\,\partial N_a/\partial X_1 \\[2pt] -F_{2I}\,\partial N_a/\partial X_2 \\[2pt] -F_{3I}\,\partial N_a/\partial X_3 \\[2pt] -F_{2I}\,\partial N_a/\partial X_3 + F_{3I}\,\partial N_a/\partial X_2 \\[2pt] -F_{1I}\,\partial N_a/\partial X_3 + F_{3I}\,\partial N_a/\partial X_1 \\[2pt] -F_{1I}\,\partial N_a/\partial X_2 + F_{2I}\,\partial N_a/\partial X_1 -\end{bmatrix}_{I=1,2,3} -$$ - -where Six rows = $\{E_{11},E_{22},E_{33},2E_{23},2E_{13},2E_{12}\}$ Voigt strain; factor 2 on shears already absorbed - -**Internal force at node $a$:** - -$$ -\mathbf{f}^{\mathrm{int}}_a = \int_{\Omega_0}\mathbf{B}_a^T\,\mathbf{S}\,dV_0 - = \int_{\Omega_0}\nabla_0 N_a\cdot(\mathbf{F}\,\mathbf{S})\,dV_0 -$$ - -where Both forms produce the same nodal force; second avoids explicit B construction - -**Convected (curvilinear) form:** - -$$ -(\mathbf{B}_a)_{IJk}^{\mathrm{conv}} -= \tfrac{1}{2}\!\left(g_{ki}\,(\mathbf{N}_a)_I\,(\mathbf{N}_a)_J\,\delta_J{}^I + \cdots\right) -$$ - -where Schematic — full convected derivation in `kinematics-convected-coordinates`; reduces to the Cartesian form when $\mathbf{G}_i=\mathbf{e}_i$ - -**Hex8 isoparametric construction:** - -$$ -N_a(\boldsymbol{\xi}) = \tfrac{1}{8}(1+\xi_1\xi_1^a)(1+\xi_2\xi_2^a)(1+\xi_3\xi_3^a),\; -\frac{\partial N_a}{\partial \mathbf{X}} = (\mathbf{J}^{\mathrm{ref}})^{-1}\cdot\frac{\partial N_a}{\partial \boldsymbol{\xi}} -$$ - -where $\boldsymbol{\xi}^a$ corner coordinates; $\mathbf{J}^{\mathrm{ref}}=\partial\mathbf{X}/\partial\boldsymbol{\xi}$ parent-reference Jacobian - -**Reduction to small strain ($\mathbf{F}\to\mathbf{I}$):** - -$$ -\lim_{\mathbf{F}\to\mathbf{I}}\mathbf{B}_a = \mathbf{B}_0^a,\qquad -\delta\mathbf{E} \to \delta\boldsymbol{\varepsilon} = \tfrac{1}{2}(\nabla_0\delta\mathbf{u}+\nabla_0\delta\mathbf{u}^T) -$$ - -where TL recovers linear elasticity exactly in the small-strain limit - -**Notation:** - -- $\mathbf{B}_a$ — Full TL B-matrix block for node $a$ -- $\mathbf{B}_0^a$ — Linear (small-strain) part; constant in time -- $\mathbf{B}_1^a(\mathbf{F})$ — Nonlinear part; depends on current $\mathbf{F}$ -- $\mathbf{F}$ — Deformation gradient at the Gauss point -- $N_a$ — Shape function for node $a$ -- $\partial N_a/\partial \mathbf{X}$ — Reference shape function gradient -- $\mathbf{J}^{\mathrm{ref}}$ — Reference parent-physical Jacobian, $\mathbf{J}^{\mathrm{ref}}=\partial \mathbf{X}/\partial \boldsymbol{\xi}$ -- $\delta\mathbf{u}_a,\delta\mathbf{E}$ — Variation of nodal displacement and Green-Lagrange strain -- $E_{IJ}$ — Green-Lagrange strain components - - -## 3. Algorithmic Implementation -**Algorithm: Construct TL B-Matrix at a Gauss Point** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{F},\,\{\partial N_a/\partial \mathbf{X}\}_{a=1}^{n_n}$ -\For{$a = 1,\ldots,n_n$} -\For{$I,J = 1,2,3 \;\text{(symmetric pair)},\,k = 1,2,3$} -\State $(\mathbf{B}_a)_{IJk} \gets \tfrac{1}{2}(F_{kI}\,\partial N_a/\partial X_J + F_{kJ}\,\partial N_a/\partial X_I)$ -\EndFor -\EndFor -\State $\text{convert to Voigt 6x3 form via the symmetric-pair index map (kinematic rule absorbs factor 2 on shears)}$ -\Return $[\mathbf{B}_a]\,\text{for}\,a=1,\ldots,n_n$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Pre-compute $\partial N_a/\partial \mathbf{X}$ once per element at startup (reference data, constant in time). Build the Voigt 6x3 form per node directly from the indicial expression to avoid the explicit symmetric-pair conversion. For hex8 / tet4 with $n_n=8/4$ nodes, fully unroll the node loop with `ti.static(range(n_n))`. Storage: $6\times 3 n_n$ floats per Gauss point — for hex8 = 144 floats. Total memory across all Gauss points may be too large; recompute per Newton iteration if memory is tight. - - -**Algorithm: Internal Force via $\mathbf{B}^T\mathbf{S}$ vs $\nabla_0 N_a\cdot\mathbf{P}$** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{S}\,\text{(Voigt 6-vector)},\,\mathbf{F},\,\partial N_a/\partial \mathbf{X}$ -\State $\text{Option 1: } \mathbf{f}^{\mathrm{int}}_a \mathrel{+}= \mathbf{B}_a^T\,\{\mathbf{S}\}\,w_g\,\det J_g$ -\State $\text{Option 2: } \mathbf{P} \gets \mathbf{F}\,\mathbf{S},\;\mathbf{f}^{\mathrm{int}}_{a,i} \mathrel{+}= P_{iJ}\,(\partial N_a/\partial X_J)\,w_g\,\det J_g$ -\Return $\mathbf{f}^{\mathrm{int}}_a$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Option 2 (PK1 / nominal product) avoids storing the full B-matrix and is faster on GPU when $n_n$ is large (high-order elements). Option 1 is convenient when the same B-matrix is reused for $\mathbf{B}^T\mathbb{C}^{SE}\mathbf{B}$ in the material tangent (`fem-tl-linearization`). Choose based on whether implicit / explicit dynamics is being run. - - -**Algorithm: Convert from Indicial to Voigt B-Matrix** - -$$ -\begin{algorithmic} -\State $\text{input} \colon (\mathbf{B}_a)_{IJk}\,\text{indicial}$ -\For{$\alpha = 1,\ldots,6 \;\text{Voigt index}$} -\State $(I,J) \gets \mathrm{voigt\_pair}(\alpha) \in \{(1,1),(2,2),(3,3),(2,3),(1,3),(1,2)\}$ -\For{$k = 1,2,3$} -\If{$I = J$} -\State $[\mathbf{B}_a]_{\alpha k} \gets (\mathbf{B}_a)_{IIk}$ -\Else -\State $[\mathbf{B}_a]_{\alpha k} \gets 2\,(\mathbf{B}_a)_{IJk} \;\text{(kinematic Voigt: factor 2 on shears)}$ -\EndIf -\EndFor -\EndFor -\Return $[\mathbf{B}_a]_{6\times 3}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Inline the conversion inside the assembly kernel — never as a separate routine. The factor 2 on shears is absorbed into the off-diagonal Voigt rows; failing to apply it produces shear stresses half their correct values. Tag every B-matrix array with `_voigt_kin` to make the convention explicit at API boundaries. - - - -## 4. Known Pitfalls -**Factor of 2 on shear strains in Voigt-form B-matrix:** The kinematic Voigt rule requires multiplying off-diagonal (shear) rows of $[\mathbf{B}_a]$ by 2 so that $\{\mathbf{S}\}^T[\mathbf{B}_a]\delta\mathbf{u}_a$ reproduces the indicial $\mathbf{S}\colon\delta\mathbf{E}$. Forgetting it halves the shear contribution to the internal force; the bug is silent on uniaxial tests but obvious on shear-dominated benchmarks. - - -**Mismatch between $\mathbf{B}_0$ and $\mathbf{B}_1$ conventions:** Some references define $\mathbf{B}_1$ with $F_{kI}\partial N_a/\partial X_J$ (full $\mathbf{F}$) and others with $H_{kI}\partial N_a/\partial X_J$ (displacement gradient $\mathbf{H}=\mathbf{F}-\mathbf{I}$). The two differ by exactly $\mathbf{B}_0$, so $\mathbf{B}=\mathbf{B}_0+\mathbf{B}_1$ remains the same — but mixing the conventions in a code can produce a stiffness off by $\mathbf{B}_0$ in the linear part. Document and stick with one convention. - - -**Sign error in $\mathbf{F}$ dependence:** $\mathbf{F}=\mathbf{I}+\nabla_0\mathbf{u}$ — note the sign on $\nabla_0\mathbf{u}$ is positive. A common slip in code is $\mathbf{F}=\mathbf{I}-\nabla_0\mathbf{u}$ (confusion with $\mathbf{F}^{-1}\approx\mathbf{I}-\nabla_0\mathbf{u}$ at small strain). The wrong sign makes $\mathbf{B}_1$ negative-definite and Newton iteration diverges immediately under tension. - - -**Double-counting symmetric variations:** $\delta\mathbf{E}$ is symmetric ($\delta\mathbf{E}=\delta\mathbf{E}^T$); summing over all 9 components rather than the 6 unique ones double-counts off-diagonal entries and produces a residual wrong by a factor of 2 in shear blocks. Iterate over $I\le J$ when constructing $\delta\mathbf{E}$ in tensor form, OR use the Voigt 6-vector form with the kinematic rule's factor 2 already baked in. - - -**Performance issues with dense $\mathbf{B}_1$ storage for high-order elements:** For hex20 / hex27 / spectral-element discretisations $n_n$ grows quickly (20-125 nodes per element) and storing the full $6\times 3 n_n$ B-matrix per Gauss point exceeds GPU register / shared-memory budgets. Either compute B on the fly (recompute per kernel call) or use the matrix-free $\mathbf{B}^T\mathbf{S}$ pattern with $\mathbf{P}=\mathbf{F}\mathbf{S}$ (`fem-tl-matrix-free-action`). - - -**Mixing reference and current shape function gradients:** In TL the gradients are $\partial N_a/\partial\mathbf{X}$ (reference, constant in time). In UL they are $\partial N_a/\partial\mathbf{x}=(\partial N_a/\partial\mathbf{X})\mathbf{F}^{-1}$ (current, updated each step). Using the latter inside a TL kernel halves the cost of the conversion but corrupts the strain-displacement operator (the B-matrix would need additional terms to compensate). Pick TL or UL; never mix. - - -**Asymmetric stiffness from inconsistent index pairing:** The B-matrix construction $(\mathbf{B}_a)_{IJk}=\tfrac12(F_{kI}\partial N_a/\partial X_J + F_{kJ}\partial N_a/\partial X_I)$ has a specific index-pair symmetry. A common typo swaps $\partial N_a/\partial X_J$ to $\partial N_a/\partial X_I$ on one side and produces a non-symmetric $\delta\mathbf{E}$. The downstream $\mathbf{K}_m=\int\mathbf{B}^T\mathbb{C}^{SE}\mathbf{B}\,dV_0$ becomes asymmetric and breaks Cholesky / LDL solvers. - - -**Hex8 element with reduced integration:** Hex8 with full Gauss integration (8 GPs) gives the correct B-matrix per GP. Reduced integration (1 GP at the centroid) is cheaper but introduces zero-energy modes (hourglass) that the B-matrix alone cannot stabilise — additional hourglass control is needed. The B-matrix construction is unchanged; the issue is the chosen quadrature rule. - - -## 5. References -- Belytschko, Liu, Moran & Elkhodary (2014) — Nonlinear Finite Elements for Continua and Structures, 2nd ed., Ch. 4-6 (TL B-matrix construction, Voigt form, hex8 / tet4 specifics) -- Bathe (1975) — Finite element formulations for large deformation dynamic analysis ($\mathbf{B}_0+\mathbf{B}_1$ split, original notation) -- de Borst, Crisfield, Remmers & Verhoosel (2012) — Nonlinear Finite Element Analysis of Solids and Structures, 2nd ed. (Green strain B-matrix, 2D / 3D Voigt forms with engineering shear) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fem-tl-linearization.md b/packages/akms/src/akms/_bundled/global_nodes/fem-tl-linearization.md deleted file mode 100644 index dab5277..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fem-tl-linearization.md +++ /dev/null @@ -1,244 +0,0 @@ ---- -id: fem-tl-linearization -title: Consistent Linearization in TL Framework -domain: computational-mechanics -subdomain: finite-elements -tags: -- fem -- finite-strain -- total-lagrangian -- tangent-stiffness -- newton -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fem-tl-weak-form - type: requires - weight: 1.0 - note: Linearisation acts on the residual derived from the TL weak form -- to: fem-tl-b-matrix - type: requires - weight: 1.0 - note: Material tangent uses $\mathbf{B}^T\mathbb{C}^{SE}\mathbf{B}$ kernels -- to: stress-piola-kirchhoff - type: requires - weight: 1.0 - note: Geometric stiffness uses the current PK2 stress -- to: tensor-derivatives-tensors - type: requires - weight: 0.7 - note: $\mathbb{C}^{SE}=\partial \mathbf{S}/\partial \mathbf{E}$ is a tensor-of-tensor derivative -- to: fem-tl-matrix-free-action - type: feeds-into - weight: 1.0 - note: Matrix-free action evaluates $(\mathbf{K}_m+\mathbf{K}_\sigma)\mathbf{v}$ without storing $\mathbf{K}$ -- to: fem-newton-raphson - type: feeds-into - weight: 1.0 - note: Tangent stiffness drives Newton iteration -context_size: large -reading_priority: full -load_with: -- fem-tl-weak-form -- fem-tl-b-matrix -content_ref: null -akms_schema: v2 ---- - -# Consistent Linearization in TL Framework - -## Summary -Consistent linearisation of the TL residual $\mathbf{r}(\mathbf{u})=\mathbf{f}^{\mathrm{int}}(\mathbf{u})-\mathbf{f}^{\mathrm{ext}}=\mathbf{0}$ produces the tangent stiffness $\mathbf{K}=\partial\mathbf{f}^{\mathrm{int}}/\partial\mathbf{u}=\mathbf{K}_m+\mathbf{K}_\sigma$. The MATERIAL stiffness $\mathbf{K}_m=\int_{\Omega_0}\mathbf{B}^T\,\mathbb{C}^{SE}\,\mathbf{B}\,dV_0$ uses the constitutive tangent $\mathbb{C}^{SE}=\partial\mathbf{S}/\partial\mathbf{E}$ and the linearised B-matrix; symmetric whenever $\mathbb{C}^{SE}$ has major symmetry (true for hyperelasticity / associative plasticity). The GEOMETRIC (initial-stress) stiffness $\mathbf{K}_\sigma$ comes from the second variation of $\mathbf{E}$ and has the explicit form $K^{\sigma}_{ab,ij}=\delta_{ij}\int_{\Omega_0}(\partial N_a/\partial X_K)(\partial N_b/\partial X_L)\,S_{KL}\,dV_0$ — a scalar contracting with $\delta_{ij}$, hence rotation-invariant. Newton iteration uses $\mathbf{K}\,\Delta\mathbf{u}=-\mathbf{r}$. Dropping $\mathbf{K}_\sigma$ degrades convergence from quadratic to linear at finite strain. - - -## 1. Core Concept -In TL-FEM the residual $\mathbf{r}(\mathbf{u})$ is nonlinear in $\mathbf{u}$ for two structural reasons: (1) the constitutive law $\mathbf{S}(\mathbf{C})$ is nonlinear; (2) the strain-displacement operator $\mathbf{B}(\mathbf{F})$ depends on displacement through $\mathbf{F}$. Differentiating the residual produces two contributions, mirroring exactly these two sources of nonlinearity. The MATERIAL tangent $\mathbf{K}_m$ comes from differentiating $\mathbf{S}$ at fixed $\mathbf{B}$: it is structurally identical to the linear-elasticity stiffness with $\mathbb{C}^{SE}=\partial\mathbf{S}/\partial\mathbf{E}$ replacing $\mathbb{C}^{\mathrm{linear}}$, and it is the only piece needed in geometrically linear analyses. The GEOMETRIC tangent $\mathbf{K}_\sigma$ comes from differentiating $\mathbf{B}$ at fixed $\mathbf{S}$: it represents the "initial stress" effect that resists infinitesimal deformations from a stressed state and is essential at finite strain. Without $\mathbf{K}_\sigma$, Newton iteration cannot achieve quadratic convergence at finite strain; with it, geometric instabilities (Euler buckling, snap-through) emerge naturally as eigenvalue problems on $\mathbf{K}_m+\mathbf{K}_\sigma$. - - -## 2. Mathematical Formulation -Throughout, $\mathbf{u}$ is the global nodal-displacement vector; $\mathbf{r}(\mathbf{u})$ residual; $\mathbf{B}_a$ TL B-matrix block for node $a$ (`fem-tl-b-matrix`); $\mathbf{S}$ PK2 stress; $\mathbb{C}^{SE}=\partial\mathbf{S}/\partial\mathbf{E}=2\partial\mathbf{S}/\partial\mathbf{C}$; $\nabla_0 N_a=\partial N_a/\partial\mathbf{X}$. - - -**Tangent stiffness from residual:** - -$$ -\mathbf{K}_{ab} = \frac{\partial \mathbf{f}^{\mathrm{int}}_a}{\partial \mathbf{u}_b} - = \mathbf{K}^m_{ab} + \mathbf{K}^\sigma_{ab} -$$ - -where Material + geometric decomposition; subscripts $a,b$ index nodes, components $i,j$ implied - -**Material tangent (Voigt form):** - -$$ -\mathbf{K}^m_{ab} = \int_{\Omega_0}\,[\mathbf{B}_a]^T\,[\mathbb{C}^{SE}]\,[\mathbf{B}_b]\,dV_0 -$$ - -where $[\mathbb{C}^{SE}]$ is the $6\times 6$ Voigt material tangent; $[\mathbf{B}_a]$ is the $6\times 3$ TL B-matrix block - -**Material tangent (indicial form):** - -$$ -K^m_{ab,ij} = \int_{\Omega_0}\,F_{iI}\,\frac{\partial N_a}{\partial X_J}\, - C^{SE}_{IJKL}\, - F_{jK}\,\frac{\partial N_b}{\partial X_L}\,dV_0 -$$ - -where Sum over $I,J,K,L$; $F_{iI}$'s come from $\mathbf{B}_a$'s $\mathbf{F}$ dependence - -**Geometric (initial-stress) stiffness:** - -$$ -K^\sigma_{ab,ij} = \delta_{ij}\,\int_{\Omega_0}\,\frac{\partial N_a}{\partial X_K}\, - \frac{\partial N_b}{\partial X_L}\, - S_{KL}\,dV_0 -$$ - -where Scalar weight per node-pair, multiplied by $\delta_{ij}\mathbf{I}_{3\times 3}$ — rotation-invariant - -**Symmetry properties:** - -$$ -\mathbf{K}_m = \mathbf{K}_m^T \;\Leftrightarrow\; C^{SE}_{IJKL} = C^{SE}_{KLIJ},\qquad -\mathbf{K}_\sigma = \mathbf{K}_\sigma^T\;\;\text{always (since $\\mathbf{S}=\\mathbf{S}^T$)} -$$ - -where Total $\mathbf{K}$ symmetric for hyperelasticity / associative plasticity; non-associative plasticity breaks $\mathbf{K}_m$ symmetry - -**Newton iteration:** - -$$ -\mathbf{K}(\mathbf{u}^\nu)\,\Delta\mathbf{u}^\nu = -\mathbf{r}(\mathbf{u}^\nu),\qquad -\mathbf{u}^{\nu+1} = \mathbf{u}^\nu + \Delta\mathbf{u}^\nu -$$ - -where Quadratic convergence near the solution; $\nu$ iteration index - -**Algorithmically consistent vs continuum tangent:** - -$$ -\mathbb{C}^{SE,\mathrm{alg}} = \frac{\partial \mathbf{S}_{n+1}^{\mathrm{algorithm}}}{\partial \mathbf{E}_{n+1}} -\;\ne\; -\mathbb{C}^{SE,\mathrm{cont}} = \frac{\partial \mathbf{S}}{\partial \mathbf{E}}\,\bigg|_{\mathbf{E}_{n+1}} -\;\;\text{for finite-step return mapping} -$$ - -where Use $\mathbb{C}^{SE,\mathrm{alg}}$ for quadratic Newton convergence in elastoplasticity - -**Updated-Lagrangian limit:** - -$$ -\mathbf{F} \to \mathbf{I},\,\mathbf{S}\to\boldsymbol{\sigma},\,\mathbb{C}^{SE}\to\mathbb{C}^\tau, -\;\Rightarrow\; \mathbf{K}^m \to \int_{\Omega_t}\,[\mathbf{B}^{UL}]^T[\mathbb{C}^\tau][\mathbf{B}^{UL}]\,dv,\; - \mathbf{K}^\sigma \to \int_{\Omega_t}\,\nabla N_a\nabla N_b\,\boldsymbol{\sigma}\,dv -$$ - -where Recovers the UL form when current configuration is taken as the reference - -**Notation:** - -- $\mathbf{r}(\mathbf{u})$ — Residual, $\mathbf{r}=\mathbf{f}^{\mathrm{int}}-\mathbf{f}^{\mathrm{ext}}$ -- $\mathbf{K}$ — Tangent stiffness matrix, $\mathbf{K}=\mathbf{K}_m+\mathbf{K}_\sigma$ -- $\mathbf{K}_m,\mathbf{K}_\sigma$ — Material / geometric (initial-stress) stiffness -- $\mathbb{C}^{SE}$ — PK2-Green-Lagrange material tangent, $\mathbb{C}^{SE}=\partial \mathbf{S}/\partial \mathbf{E}$ -- $\mathbf{B}_a$ — TL B-matrix block for node $a$ -- $\nabla_0 N_a$ — Reference shape function gradient $\partial N_a/\partial \mathbf{X}$ -- $\mathbf{S}$ — Second Piola-Kirchhoff stress -- $\Delta\mathbf{u}^\nu$ — Newton increment at iteration $\nu$ - - -## 3. Algorithmic Implementation -**Algorithm: Element Tangent Stiffness Assembly (TL)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \{\mathbf{u}_a\}_{a=1}^{n_n},\,\text{constitutive law providing } \mathbb{C}^{SE,\mathrm{alg}}$ -\State $\mathbf{K}_e \gets \mathbf{0} \in \mathbb{R}^{3 n_n \times 3 n_n}$ -\For{$\text{each Gauss point } g$} -\State $\mathbf{F}_g \gets \mathbf{I}+\sum_a \mathbf{u}_a\otimes\nabla_0 N_a(\boldsymbol{\xi}_g)$ -\State $\mathbf{S}_g,\,\mathbb{C}^{SE,\mathrm{alg}}_g \gets \mathrm{ConstitutiveUpdate}(\mathbf{F}_g,\,\text{state}_n)$ -\State $\text{build } [\mathbf{B}_a^g]_{6\times 3}\,\text{for each node from}\,\mathbf{F}_g,\,\nabla_0 N_a$ -\For{$a,b = 1,\ldots,n_n$} -\State $\mathbf{K}^m_{e,ab} \mathrel{+}= [\mathbf{B}_a^g]^T\,[\mathbb{C}^{SE,\mathrm{alg}}_g]\,[\mathbf{B}_b^g]\,w_g\,\det J_g$ -\State $K^\sigma_{e,ab,ij} \mathrel{+}= \delta_{ij}\,(\nabla_0 N_a^T\,\mathbf{S}_g\,\nabla_0 N_b)\,w_g\,\det J_g$ -\EndFor -\EndFor -\State $\mathbf{K}_e \gets \mathbf{K}^m_e + \mathbf{K}^\sigma_e$ -\State $\text{scatter } \mathbf{K}_e \text{ into the global stiffness}$ -\Return $\mathbf{K}_e$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Single fused element kernel. The triple product $\mathbf{B}^T\mathbb{C}^{SE}\mathbf{B}$ dominates the cost: $6\times 3 \cdot 6\times 6 \cdot 6\times 3 = 6\times 3$ per pair, repeated $n_n^2$ times per Gauss point. For hex8 ($n_n=8$, 8 Gauss points) the per-element cost is $\sim 9000$ FMAs. The geometric $\mathbf{K}_\sigma$ block is much cheaper ($\sim n_n^2$ scalar contractions per Gauss point). Use `ti.atomic_add` for global scatter or pre-color elements for race-free parallel assembly. - - -**Algorithm: Newton-Raphson Outer Iteration** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{u}^0,\,\text{tol}\,\tau,\,\text{max iter}\,K$ -\For{$\nu = 0,\ldots,K-1$} -\State $\mathbf{r}^\nu \gets \mathbf{f}^{\mathrm{int}}(\mathbf{u}^\nu) - \mathbf{f}^{\mathrm{ext}}$ -\If{$\|\mathbf{r}^\nu\|/\|\mathbf{f}^{\mathrm{ext}}\| < \tau$} -\State $\textbf{break}$ -\EndIf -\State $\mathbf{K}^\nu \gets \mathbf{K}(\mathbf{u}^\nu) \;\text{(modified Newton: skip update some iterations)}$ -\State $\Delta \mathbf{u}^\nu \gets -(\mathbf{K}^\nu)^{-1}\,\mathbf{r}^\nu$ -\State $\mathbf{u}^{\nu+1} \gets \mathbf{u}^\nu + \Delta\mathbf{u}^\nu$ -\EndFor -\Return $\mathbf{u}^{\nu+1},\,\nu\,\text{(iteration count)}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Combine the residual / tangent assembly into a single sweep when possible — every inner Gauss-point evaluation gives both. For modified Newton (Jacobian held fixed for several iterations) skip the tangent reassembly. For load-stepping difficult problems use line search ($\mathbf{u}^{\nu+1}=\mathbf{u}^\nu+\alpha\Delta\mathbf{u}^\nu$ with $\alpha$ chosen by Armijo or bisection) before declaring divergence. Track residual norm history for adaptive load stepping. - - -**Algorithm: Symmetry Check on Tangent** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{K}_e\,\text{element tangent}$ -\State $r \gets \|\mathbf{K}_e - \mathbf{K}_e^T\|_F/\|\mathbf{K}_e\|_F$ -\If{$r > \tau_{\mathrm{sym}}\,(\sim 10^{-10})$} -\State $\text{warning: tangent is non-symmetric beyond round-off}$ -\EndIf -\Return $r,\,\mathbf{K}_e$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Diagnostic to run on at least one element during development. Genuine non-symmetry comes from non-associative plasticity, viscoplastic Perzyna laws with rate-dependent flow, or contact friction; round-off non-symmetry is $\mathcal{O}(10^{-12})$. If sources of non-symmetry are intentional, switch to a non-symmetric solver (GMRES, Bi-CGSTAB) instead of CG / LDLT. - - - -## 4. Known Pitfalls -**Forgetting geometric stiffness:** Dropping $\mathbf{K}_\sigma$ from the tangent while keeping $\mathbf{K}_m$ produces an "initial-stiffness" approximation that is widely used in textbook problems but degrades quadratic to linear convergence at finite strain and misses geometric instabilities (Euler buckling, snap-through). Newton iteration may still converge for small steps but at a much higher iteration count and with poor robustness. - - -**Wrong index pairing in $\mathbf{K}_\sigma$:** The geometric stiffness has the EXPLICIT form $K^\sigma_{ab,ij}=\delta_{ij}\int(\partial N_a/\partial X_K)(\partial N_b/\partial X_L) S_{KL}\,dV_0$ — the $\delta_{ij}$ identity in spatial indices is what makes $\mathbf{K}_\sigma$ rotation-invariant. Constructing $\mathbf{K}_\sigma$ as a generic $3\times 3$ matrix per node-pair (as in the material part) destroys rotation invariance and yields a stiffness that depends on the global frame. - - -**Asymmetric stiffness from inconsistent material vs geometric contributions:** $\mathbf{K}_\sigma$ is always symmetric (thanks to $\mathbf{S}=\mathbf{S}^T$); $\mathbf{K}_m$ is symmetric iff $\mathbb{C}^{SE}$ has major symmetry. Combining a non-symmetric $\mathbf{K}_m$ from non-associative plasticity with a symmetric $\mathbf{K}_\sigma$ produces a non-symmetric total stiffness — switch to GMRES / BiCGSTAB; do NOT symmetrise by averaging which silently breaks consistency. - - -**Factor of 2 in $\delta\mathbf{E}$ first variation:** The B-matrix-to-strain mapping $\delta\mathbf{E}=\sum_a\mathbf{B}_a\delta\mathbf{u}_a$ uses kinematic Voigt (factor 2 on shears). The material tangent $\mathbb{C}^{SE}$ in $6\times 6$ Voigt form must use the kinetic rule (no factor 2). Applying both kinematic or both kinetic rules introduces factor-of-4 errors in the shear stiffness that survive uniaxial verification. - - -**Continuum vs algorithmic consistent tangent:** For path-dependent constitutive laws (return mapping in plasticity), $\mathbb{C}^{SE,\mathrm{cont}}=\partial\mathbf{S}/\partial\mathbf{E}$ is NOT the same as the algorithmically consistent tangent $\mathbb{C}^{SE,\mathrm{alg}}=\partial\mathbf{S}_{n+1}^{\mathrm{numerical}}/\partial\mathbf{E}_{n+1}$ — the difference is the implicit dependence through the Newton iteration on $\Delta\gamma$. Using the continuum tangent in finite-step elastoplasticity degrades Newton from quadratic to linear; use the algorithmic tangent (`plasticity-consistent-tangent`). - - -**Mass matrix in the wrong configuration:** The TL inertial term uses the REFERENCE mass matrix $\mathbf{M}_{ab}=\int_{\Omega_0}\rho_0\,N_a N_b\,dV_0\,\mathbf{I}_{3\times 3}$ — constant in time. Some codes recompute $\mathbf{M}$ each step using current $\rho$, $dv$, which is unnecessary and wrong (the reference form is exact). Wasted CPU and corrupted dynamics if $\rho_0\to\rho$ substitution is done inconsistently. - - -**Boundary conditions imposed on the wrong side:** Dirichlet BCs in TL are imposed on the reference configuration: $\mathbf{u}=\bar{\mathbf{u}}$ on $\partial\Omega_0^u$. Imposing them on the current configuration (a habit from UL) introduces a moving-boundary subproblem and corrupts the residual structure. Validate BC application by zero-displacement test on a moving / rotating body — internal stress should remain zero. - - -## 5. References -- Belytschko, Liu, Moran & Elkhodary (2014) — Nonlinear Finite Elements for Continua and Structures, 2nd ed., Ch. 6 (consistent linearisation, $\mathbf{K}_m+\mathbf{K}_\sigma$, Newton-Raphson, algorithmically consistent tangent) -- Bathe (1975) — Finite element formulations for large deformation dynamic analysis (incremental linearised tangent stiffness) -- de Borst, Crisfield, Remmers & Verhoosel (2012) — Nonlinear Finite Element Analysis of Solids and Structures, 2nd ed. (geometric stiffness, computational flow chart for nonlinear FEM) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fem-tl-matrix-free-action.md b/packages/akms/src/akms/_bundled/global_nodes/fem-tl-matrix-free-action.md deleted file mode 100644 index ab79090..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fem-tl-matrix-free-action.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: fem-tl-matrix-free-action -title: Matrix-Free Internal Force & Tangent Action -domain: computational-mechanics -subdomain: finite-elements -tags: -- fem -- finite-strain -- total-lagrangian -- matrix-free -- gpu -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fem-tl-weak-form - type: requires - weight: 1.0 -- to: fem-tl-linearization - type: requires - weight: 1.0 -- to: fem-tl-b-matrix - type: requires - weight: 0.9 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Matrix-Free Internal Force & Tangent Action - -## Summary - -Matrix-free total Lagrangian finite element formulations evaluate internal force residual vectors and tangent stiffness matrix-vector actions without explicitly assembling or storing global sparse stiffness matrices. By fusing element restriction operators, basis polynomial evaluations, and quadrature-point constitutive updates into GPU-accelerated compute kernels, matrix-free methods overcome memory bandwidth limits in high-order iterative solvers. - -## 1. Core Concept - -In non-linear finite strain solid mechanics, traditional finite element solvers assemble and store large sparse tangent stiffness matrices at each Newton iteration. For large-scale or high-order discretizations, sparse matrix assembly and storage become bottlenecked by GPU memory capacity and memory bandwidth. Matrix-free operator evaluations eliminate global matrix assembly by directly computing the action of the residual vector and linearized tangent Jacobian on candidate displacement vectors. This is achieved via partial assembly, which composes element restriction operators, quadrature-point basis evaluations, point-wise material constitutive updates (incorporating Second Piola-Kirchhoff stresses S and material tangent moduli C^{SE}), and geometric stiffness actions in a single fused computational pass. - -## 2. Mathematical Formulation - -**Matrix-Free Internal Force Residual Evaluation** -$$ -f^{\mathrm{int}} = \sum_{e} E_e^T \left( [B_I \quad B_{\xi}]^T W^e \Lambda \begin{bmatrix} f_0 \\ f_1 \end{bmatrix} \right) -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Sec. II-B, Eqs. 8–10, pp. 2–3_ - -**Matrix-Free Action of Total Lagrangian Tangent Jacobian** -$$ -J \, \mathrm{d}u = \sum_{e} E_e^T \left( [B_I \quad B_{\xi}]^T W^e \Lambda \begin{bmatrix} \hat{f}_{0,0} & \hat{f}_{0,1} \\ \hat{f}_{1,0} & \hat{f}_{1,1} \end{bmatrix} [B_I \quad B_{\xi}] E_e \, \mathrm{d}u \right) -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Sec. II-B, Eq. 11, p. 3_ - -**Total Lagrangian Material and Geometric Tangent Moduli Split** -$$ -K^{\mathrm{mat}}_{0IJ} = \int_{\Omega_0} B_{0I}^T C^{SE} B_{0J} \, \mathrm{d}\Omega_0, \quad K^{\mathrm{geo}}_{0IJ} = I \int_{\Omega_0} B_{0I}^T S B_{0J} \, \mathrm{d}\Omega_0 -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 6.5, p. 364; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.4.1, Eqs. 3.99–3.102, pp. 94–96_ - -**Notation:** -{'f^{\\mathrm{int}}': 'Assembled global internal force vector.', 'J': 'Global Jacobian matrix operator (tangent stiffness).', 'E_e': 'Element restriction operator mapping global DOFs to local element DOFs.', 'B_I, B_{\\xi}': 'Element basis functions and parametric gradient evaluation matrices at quadrature points.', 'W^e': 'Quadrature integration weight tensor.', 'C^{SE}': 'Second Piola-Kirchhoff material tangent constitutive tensor.', 'S': 'Second Piola-Kirchhoff stress tensor.', '\\mathrm{d}u': 'Vector of incremental nodal displacements.'} - - -## 3. Algorithmic Implementation - -**Matrix-Free Tangent Stiffness Action Algorithm** -$$ -\begin{algorithmic} -\State $Given global displacement vector u, direction vector \mathrm{d}u, mesh connectivity, and material parameters$ -\State $Initialize global action vector y \gets 0$ -\For{$e \gets 1 \text{ to } n_e$} -\State $Gather local element displacement u_e \gets E_e u \text{ and direction } \mathrm{d}u_e \gets E_e \mathrm{d}u$ -\State $Interpolate quadrature displacements u_q \gets B_I u_e \text{ and gradients } \nabla_{\xi} u_q \gets B_{\xi} u_e$ -\State $Compute deformation gradient F_q = I + \nabla_X u_q \text{ and strain increment } \mathrm{d}E_q$ -\State $Evaluate point-wise linearized tangent response \hat{f}_{q} \gets \Lambda(F_q, C^{SE}_q, S_q) \cdot [B_I \quad B_{\xi}] \mathrm{d}u_e$ -\State $Apply quadrature weights and basis transpose w_e \gets [B_I \quad B_{\xi}]^T (W^e \cdot \hat{f}_{q})$ -\State $Scatter accumulate into global action vector y \gets y + E_e^T w_e$ -\EndFor -\Return $y$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Sec. II-B, Eqs. 8–11, pp. 2–3_ - - -## 4. Known Pitfalls - -- **High Memory Bandwidth Bottlenecks from Explicit Matrix Assembly**: Assembling and storing global sparse tangent stiffness matrices for high-order finite element discretizations imposes severe GPU memory bandwidth limitations and high storage overhead. Mitigation: Use matrix-free operator evaluations ("partial assembly") where basis evaluations, quadrature point stress updates, and element restrictions are fused into high-throughput parallel compute kernels. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Sec. I & Sec. II-B, Fig. 7, pp. 1, 4)_ -- **Inconsistent Tangent Linearization in Matrix-Free Action**: Computing the Jacobian action J \mathrm{d}u using un-linearized stress states or omitting geometric stiffness contributions (K^{\mathrm{geo}}) destroys the quadratic convergence of Krylov-Newton solvers. Mitigation: Ensure that point-wise linearization at quadrature points accounts for both material tangent moduli C^{SE} and initial stress geometric terms S. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 6.5, p. 364; Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Sec. II-A & Sec. II-B, pp. 2–3)_ - -## References - -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p-Multigrid.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/fem-tl-weak-form.md b/packages/akms/src/akms/_bundled/global_nodes/fem-tl-weak-form.md deleted file mode 100644 index 9f1ea9c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fem-tl-weak-form.md +++ /dev/null @@ -1,251 +0,0 @@ ---- -id: fem-tl-weak-form -title: TL Weak Form & Internal Virtual Work -domain: computational-mechanics -subdomain: finite-elements -tags: -- fem -- finite-strain -- total-lagrangian -- variational -- weak-form -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: stress-piola-kirchhoff - type: requires - weight: 1.0 - note: TL weak form integrates $\mathbf{S}\colon\delta\mathbf{E}$ over $\Omega_0$ -- to: kinematics-strain-tensors - type: requires - weight: 1.0 - note: $\delta\mathbf{E}$ is the variation of Green-Lagrange strain -- to: kinematics-motion-deformation-gradient - type: requires - weight: 1.0 - note: Discrete $\mathbf{F}_h$ built from nodal displacements via shape function gradients -- to: fem-tl-b-matrix - type: feeds-into - weight: 1.0 - note: $\delta\mathbf{E}=\sum_a \mathbf{B}_a\,\delta\mathbf{u}_a$ is the canonical use of the TL B-matrix -- to: fem-tl-linearization - type: feeds-into - weight: 1.0 - note: Linearisation of the residual produces $\mathbf{K}=\mathbf{K}_m+\mathbf{K}_\sigma$ -context_size: medium -reading_priority: full -load_with: -- stress-piola-kirchhoff -- fem-tl-b-matrix -content_ref: null -akms_schema: v2 ---- - -# TL Weak Form & Internal Virtual Work - -## Summary -Total-Lagrangian (TL) FEM formulates equilibrium on the reference (undeformed) configuration. The principle of virtual work in PK2 form reads $\int_{\Omega_0}\mathbf{S}\colon\delta\mathbf{E}\,dV_0=\int_{\Omega_0}\rho_0(\mathbf{b}_0-\dot{\mathbf{v}})\cdot\delta\mathbf{u}\,dV_0+\int_{\partial\Omega_0^t}\bar{\mathbf{t}}_0\cdot\delta\mathbf{u}\,dA_0$, where $\delta\mathbf{E}=\mathrm{sym}(\mathbf{F}^T\nabla_0\delta\mathbf{u})=\tfrac12(\mathbf{F}^T\nabla_0\delta\mathbf{u}+\nabla_0\delta\mathbf{u}^T\mathbf{F})$. The Piola-equivalent form $\int_{\Omega_0}\mathbf{P}\colon\delta\mathbf{F}\,dV_0$ uses the nominal stress and the variation of $\mathbf{F}$. Discretization $\mathbf{u}_h=\sum_a N_a(\mathbf{X})\mathbf{u}_a$ with reference shape function gradients $\partial N_a/\partial\mathbf{X}$ produces the discrete deformation gradient $\mathbf{F}_h=\mathbf{I}+\sum_a (\partial N_a/\partial\mathbf{X})\otimes\mathbf{u}_a$ and the internal force vector $\mathbf{f}^{\mathrm{int}}_a=\sum_{\mathrm{GP}}\mathbf{B}_a^T\mathbf{S}\,W_{\mathrm{GP}}\det J_{\mathrm{ref}}$ — assembled element-by-element on the fixed reference mesh, then advanced via Newton-Raphson. - - -## 1. Core Concept -Total-Lagrangian FEM treats the reference configuration $\Omega_0$ as the integration domain throughout the simulation: shape functions, Gauss points, and quadrature weights are fixed in time, and only the displacement / stress / strain fields evolve. The weak form derives from the reference-configuration equilibrium $\nabla_0\cdot\mathbf{P}+\rho_0\mathbf{b}_0=\rho_0\dot{\mathbf{v}}$ via test-function multiplication and integration-by-parts; the natural pairing is $\mathbf{P}\colon\delta\mathbf{F}=\mathbf{S}\colon\delta\mathbf{E}$ (Piola transformation), so the same residual can be expressed in either nominal or PK2 form. PK2 is preferred for hyperelasticity because $\mathbf{S}=\partial\psi/\partial\mathbf{E}$ derives directly from the strain-energy potential, and for elastoplasticity in the multiplicative split because the constitutive update is performed in PK2 form on the intermediate configuration. The variation $\delta\mathbf{E}$ couples to the displacement variation through the TL B-matrix $\mathbf{B}_a=\mathbf{B}_0+\mathbf{B}_1(\mathbf{u})$, which has a constant linear part (small-strain B-matrix) and a displacement-dependent nonlinear part — the latter is what makes finite-strain TL nonlinear in displacement. - - -## 2. Mathematical Formulation -Throughout, $\Omega_0$ is the reference body, $\partial\Omega_0=\partial\Omega_0^u\cup\partial\Omega_0^t$ split into Dirichlet / Neumann boundaries. $\rho_0$ reference density, $\mathbf{b}_0$ body force per unit reference mass, $\bar{\mathbf{t}}_0$ prescribed nominal traction on $\partial\Omega_0^t$. Indices: lower-case Latin spatial, upper-case Latin material; both $1$-$3$. - - -**Reference-configuration equation of motion:** - -$$ -\nabla_0\cdot\mathbf{P} + \rho_0\,\mathbf{b}_0 = \rho_0\,\dot{\mathbf{v}} -\;\;\text{in}\;\Omega_0,\qquad -\mathbf{P}\cdot\mathbf{n}_0 = \bar{\mathbf{t}}_0 -\;\;\text{on}\;\partial\Omega_0^t,\qquad -\mathbf{u} = \bar{\mathbf{u}} \;\;\text{on}\;\partial\Omega_0^u -$$ - -where Lagrangian strong form; $\mathbf{P}=J\boldsymbol{\sigma}\mathbf{F}^{-T}$ is nominal stress - -**Weak form in PK1 (nominal) form:** - -$$ -\int_{\Omega_0}\mathbf{P}\colon\delta\mathbf{F}\,dV_0 -= \int_{\Omega_0}\rho_0\,(\mathbf{b}_0 - \dot{\mathbf{v}})\cdot\delta\mathbf{u}\,dV_0 -+ \int_{\partial\Omega_0^t}\bar{\mathbf{t}}_0\cdot\delta\mathbf{u}\,dA_0 -$$ - -where $\delta\mathbf{F}=\nabla_0\delta\mathbf{u}$ - -**Weak form in PK2 form (Piola-transformed):** - -$$ -\int_{\Omega_0}\mathbf{S}\colon\delta\mathbf{E}\,dV_0 -= \int_{\Omega_0}\rho_0\,(\mathbf{b}_0 - \dot{\mathbf{v}})\cdot\delta\mathbf{u}\,dV_0 -+ \int_{\partial\Omega_0^t}\bar{\mathbf{t}}_0\cdot\delta\mathbf{u}\,dA_0 -$$ - -where Equivalent via $\mathbf{P}\colon\delta\mathbf{F}=\mathbf{S}\colon\delta\mathbf{E}$ - -**Variation of Green-Lagrange strain:** - -$$ -\delta\mathbf{E} = \mathrm{sym}(\mathbf{F}^T\,\nabla_0\delta\mathbf{u}) - = \tfrac{1}{2}\!\left(\mathbf{F}^T\,\nabla_0\delta\mathbf{u} - + (\nabla_0\delta\mathbf{u})^T\,\mathbf{F}\right) -$$ - -where Symmetric (kinematic) — $\delta\mathbf{E}=\delta\mathbf{E}^T$ - -**Discrete displacement field:** - -$$ -\mathbf{u}_h(\mathbf{X}) = \sum_{a=1}^{n_n} N_a(\mathbf{X})\,\mathbf{u}_a,\qquad -\mathbf{F}_h(\mathbf{X}) = \mathbf{I} + \sum_{a=1}^{n_n}\,\mathbf{u}_a\otimes\nabla_0 N_a -$$ - -where Standard isoparametric discretisation; $\mathbf{F}_h$ is element-piecewise polynomial - -**Internal force at nodal level:** - -$$ -\mathbf{f}^{\mathrm{int}}_a -= \int_{\Omega_0}\mathbf{B}_a^T\,\mathbf{S}\,dV_0 -= \int_{\Omega_0}\nabla_0 N_a\cdot(\mathbf{F}\,\mathbf{S})\,dV_0 -$$ - -where Equivalent forms; the second uses $\mathbf{P}=\mathbf{F}\mathbf{S}$ - -**External force:** - -$$ -\mathbf{f}^{\mathrm{ext}}_a = \int_{\Omega_0}N_a\,\rho_0\,\mathbf{b}_0\,dV_0 - + \int_{\partial\Omega_0^t}N_a\,\bar{\mathbf{t}}_0\,dA_0 -$$ - -where Both integrals on reference geometry; no Jacobian rescaling needed - -**Residual / equation of motion in matrix form:** - -$$ -\mathbf{r}_a(\mathbf{u}) = \mathbf{f}^{\mathrm{int}}_a(\mathbf{u}) - \mathbf{f}^{\mathrm{ext}}_a + \mathbf{M}_{ab}\,\dot{\mathbf{v}}_b = \mathbf{0} -$$ - -where Algebraic system to solve at each time step; $\mathbf{M}_{ab}=\int_{\Omega_0}\rho_0\,N_a\,N_b\,dV_0\,\mathbf{I}$ is the reference-mass matrix - -**Statics (drop inertial term):** - -$$ -\mathbf{r}_a(\mathbf{u}) = \mathbf{f}^{\mathrm{int}}_a(\mathbf{u}) - \mathbf{f}^{\mathrm{ext}}_a = \mathbf{0} -$$ - -where Solved by Newton-Raphson with tangent $\mathbf{K}=\mathbf{K}_m+\mathbf{K}_\sigma$ (`fem-tl-linearization`) - -**Notation:** - -- $\Omega_0$ — Reference (undeformed) body -- $\mathbf{u},\delta\mathbf{u}$ — Displacement field and its variation (test function) -- $\mathbf{F}$ — Deformation gradient, $\mathbf{F}=\mathbf{I}+\nabla_0\mathbf{u}$ -- $\mathbf{S},\mathbf{P}$ — PK2 and PK1 (nominal) stresses -- $\mathbf{E}$ — Green-Lagrange strain, $\mathbf{E}=\tfrac12(\mathbf{C}-\mathbf{I})$ -- $\rho_0,\mathbf{b}_0,\bar{\mathbf{t}}_0$ — Reference density / body force / prescribed nominal traction -- $N_a$ — Shape function for node $a$ -- $\nabla_0 N_a$ — Reference gradient of shape function, $\partial N_a/\partial\mathbf{X}$ -- $\mathbf{B}_a$ — TL B-matrix block for node $a$ (`fem-tl-b-matrix`) -- $\mathbf{f}^{\mathrm{int}},\mathbf{f}^{\mathrm{ext}}$ — Internal / external nodal force vectors - - -## 3. Algorithmic Implementation -**Algorithm: Element-Level Internal Force Assembly (TL, PK2 Form)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \{\mathbf{u}_a\}_{a=1}^{n_n},\;\text{element nodes; reference Gauss data}$ -\State $\mathbf{f}^{\mathrm{int}}_e \gets \mathbf{0}$ -\For{$\text{each Gauss point } g \;\text{with weight } w_g,\,\det J_g$} -\State $\mathbf{F}_g \gets \mathbf{I} + \sum_a \mathbf{u}_a\otimes\nabla_0 N_a(\boldsymbol{\xi}_g)$ -\State $\mathbf{C}_g \gets \mathbf{F}_g^T\,\mathbf{F}_g$ -\State $\mathbf{S}_g,\,(\text{state}) \gets \mathrm{ConstitutiveUpdate}(\mathbf{C}_g,\,\text{state}_n)$ -\State $\mathbf{P}_g \gets \mathbf{F}_g\,\mathbf{S}_g$ -\For{$a = 1,\ldots,n_n$} -\State $f^{\mathrm{int}}_{e,a,i} \mathrel{+}= P_{g,iJ}\,(\partial N_a/\partial X_J)\,w_g\,\det J_g$ -\EndFor -\EndFor -\State $\text{scatter } \mathbf{f}^{\mathrm{int}}_e \text{ into the global force vector}$ -\Return $\mathbf{f}^{\mathrm{int}}_e$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Single fused element kernel `@ti.kernel` parameterised by element type. Pre-compute reference shape function gradients $\partial N_a/\partial\mathbf{X}$ once per element at startup (constant in time for TL). Use `ti.atomic_add` to scatter into the global force; or pre-color elements to allow safe parallel assembly without atomics. For high-order elements ($n_n>20$) split the element into per-Gauss-point parallel blocks to manage register pressure. - - -**Algorithm: Verify Discrete Conservation by Closed-Loop Cycle** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{u}(t)\,\text{prescribed closed loop in displacement space}$ -\State $\text{compute } P_{\mathrm{int}}(t) = \int_{\Omega_0}\mathbf{S}\colon\dot{\mathbf{E}}\,dV_0$ -\State $\text{integrate over the loop:}\,\,\oint P_{\mathrm{int}}\,dt$ -\State $\text{For elastic material the integral must be zero to round-off}$ -\Return $\oint P_{\mathrm{int}}\,dt$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Diagnostic: drives the body around a path-independent loop (e.g., shear up / shear down) and integrates the internal power. For elastic constitutive laws the integrated power must vanish; failure indicates wrong stress / strain conjugacy, missing Voigt factor 2 on shear, or wrong $J$ scaling. - - -**Algorithm: External Force from Prescribed Surface Traction** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \bar{\mathbf{t}}_0(\mathbf{X},t)\,\text{on}\,\partial\Omega_0^t$ -\For{$\text{each surface element on}\,\partial\Omega_0^t$} -\For{$\text{each surface Gauss point}\,g$} -\For{$a = 1,\ldots,n_{n,\mathrm{surf}}$} -\State $f^{\mathrm{ext}}_{a,i} \mathrel{+}= N_a(\boldsymbol{\xi}_g)\,\bar{t}_{0,i}(\mathbf{X}_g,t)\,w_g\,\det J^{\mathrm{surf}}_g$ -\EndFor -\EndFor -\EndFor -\Return $\mathbf{f}^{\mathrm{ext}}_a$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Surface integrals stay on the REFERENCE surface in TL — no Nanson-formula push-forward needed because the prescribed traction is already nominal. If the user supplies Cauchy traction $\bar{\mathbf{t}}$ on the deformed surface, convert via Nanson: $\bar{\mathbf{t}}_0=J\boldsymbol{\sigma}\mathbf{F}^{-T}\mathbf{n}_0/\|\cdot\|$ (cf. `kinematics-motion-deformation-gradient`). Tag the input as `_nominal` or `_cauchy` at the API boundary. - - - -## 4. Known Pitfalls -**Confusing reference vs current divergence:** Reference equilibrium uses $\nabla_0\cdot\mathbf{P}$; current equilibrium uses $\nabla\cdot\boldsymbol{\sigma}$. Mixing the two — e.g., applying material gradients to $\boldsymbol{\sigma}$ — produces residuals integrated against the wrong configuration. Pick TL or UL once, document, validate. The variation $\delta\mathbf{u}$ is associated with the chosen configuration. - - -**Factor of 2 in $\delta\mathbf{E}$:** $\delta\mathbf{E}=\tfrac12(\mathbf{F}^T\nabla_0\delta\mathbf{u}+\nabla_0\delta\mathbf{u}^T\mathbf{F})$ — the factor 1/2 is essential to make $\delta\mathbf{E}=\delta\mathbf{E}^T$ symmetric. Forgetting it doubles the symmetric strain variation and the internal force becomes wrong by a factor of 2 in shear blocks. Always write the symmetrised form explicitly. - - -**Mixing kinetic / kinematic Voigt representations:** In Voigt form $\delta\{\mathbf{E}\}$ uses kinematic Voigt (factor 2 on shears) while $\{\mathbf{S}\}$ uses kinetic Voigt (no factor). The product $\{\mathbf{S}\}^T\{\delta\mathbf{E}\}=\mathbf{S}\colon\delta\mathbf{E}$ holds only with this convention. Substituting kinetic-Voigt $\delta\{\mathbf{E}\}$ (no factor) halves the shear contribution and silently corrupts internal energy. - - -**Dropping geometric stiffness in linearization:** The tangent $\mathbf{K}=\mathbf{K}_m+\mathbf{K}_\sigma$ has both a material and a geometric (initial-stress) contribution; dropping $\mathbf{K}_\sigma$ degrades Newton convergence from quadratic to linear at finite strain. The geometric term comes from the SECOND variation of $\mathbf{E}$ — see `fem-tl-linearization`. Always include it for finite-strain analyses. - - -**$\mathbf{S}$ paired with $\dot{\mathbf{F}}$ instead of $\dot{\mathbf{E}}$:** The conjugate strain rate of $\mathbf{S}$ is $\dot{\mathbf{E}}$, NOT $\dot{\mathbf{F}}$. The conjugate of $\dot{\mathbf{F}}$ is $\mathbf{P}$ (nominal). Pairing $\mathbf{S}\colon\dot{\mathbf{F}}$ in an internal-power expression is dimensionally ill-formed (mixed-leg vs symmetric tensors) and breaks energy balance. State the conjugacy convention at every internal-power computation. - - -**Forgetting the reference Jacobian in surface integrals:** Surface integrals on $\partial\Omega_0^t$ use $\det J^{\mathrm{surf}}_g$ from the parametric surface mapping (parent boundary $\to$ reference surface). Some codes accidentally reuse the volumetric Jacobian, producing tractions wrong by a factor proportional to surface curvature. Use a separate surface-Gauss data structure with its own quadrature weights and Jacobians. - - -**Discontinuous shape functions across element boundaries:** $\mathbf{F}_h$ has $C^0$ continuity in standard FEM (displacement is continuous, gradient is discontinuous across element edges). Computing element-level quantities and naively averaging at nodes produces visually plausible but quantitatively wrong contour plots of stress / strain. Use proper L2 / superconvergent recovery for nodal output; never average raw element-level $\mathbf{F}$ at nodes. - - -**Treating material time derivative as Eulerian partial in TL:** In TL the material derivative $\dot{(\bullet)}=\partial(\bullet)/\partial t|_{\mathbf{X}}$ is exactly the partial derivative at fixed reference label — the Eulerian advective term $\mathbf{v}\cdot\nabla(\bullet)$ does NOT appear. Adding it (a habit from UL / Eulerian fluid codes) introduces a spurious convective term and breaks the TL formulation. Material-frame is the simplest case; the advective term emerges only in UL / Eulerian formulations. - - -## 5. References -- Belytschko, Liu, Moran & Elkhodary (2014) — Nonlinear Finite Elements for Continua and Structures, 2nd ed., Ch. 4-6 (TL weak form, PK1 / PK2 equivalence, element internal force, Newton iteration) -- de Borst, Crisfield, Remmers & Verhoosel (2012) — Nonlinear Finite Element Analysis of Solids and Structures, 2nd ed. (geometrically nonlinear weak form, computational flow chart) -- Bathe (1975) — Finite element formulations for large deformation dynamic analysis (early TL formulation; conjugacy of PK2 with Green strain rate) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fem-weak-form-derivation.md b/packages/akms/src/akms/_bundled/global_nodes/fem-weak-form-derivation.md deleted file mode 100644 index 2263e71..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fem-weak-form-derivation.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -id: fem-weak-form-derivation -title: Weak Form & Variational Principles -domain: computational-mechanics -subdomain: finite-elements -tags: -- fem -- variational -- weak-form -- galerkin -- boundary-conditions -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fem-shape-functions - type: feeds-into - weight: 1.0 -- to: fem-isoparametric-mapping - type: feeds-into - weight: 1.0 -- to: fem-assembly-algorithm - type: feeds-into - weight: 0.9 -- to: fem-tl-weak-form - type: refines - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Weak Form & Variational Principles - -## Summary - -The weak form converts local differential momentum balance equations into an equivalent integral scalar statement over a continuum domain by testing against arbitrary kinematically admissible virtual displacement fields. Through integration by parts and the Gauss divergence theorem, the weak form relaxes continuity requirements on stress fields, incorporates Neumann natural boundary conditions directly into boundary integrals, and serves as the foundation for Ritz-Galerkin finite element spatial discretizations. - -## 1. Core Concept - -The principle of virtual work provides the fundamental weak form for continuum mechanics problems. Starting from local strong-form momentum balance \nabla \cdot \boldsymbol{\sigma} + \rho \mathbf{b} = \rho \ddot{\mathbf{u}}, the governing differential equation is multiplied by an arbitrary test function (virtual displacement \delta \mathbf{u}) and integrated over the continuum volume. Applying tensor divergence identities reduces second-order spatial derivatives to first-order derivatives. Essential (Dirichlet) boundary conditions are enforced strongly on the trial displacement space, requiring test functions to vanish on essential boundary surfaces. Natural (Neumann) surface tractions enter the weak formulation directly as boundary integrals. The Galerkin method selects finite-dimensional trial and test spaces from the same polynomial shape function basis. - -## 2. Mathematical Formulation - -**Strong Form Differential Balance** -$$ -\nabla \cdot \boldsymbol{\sigma} + \rho \mathbf{b} = \rho \ddot{\mathbf{u}} \quad \text{in } V -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.1, Eq. 2.4, p. 32; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 2.2.4, p. 23_ - -**Principle of Virtual Work (Weak Form)** -$$ -\int_V \boldsymbol{\sigma} : \nabla(\delta \mathbf{u}) \, \mathrm{d}V + \int_V \rho \ddot{\mathbf{u}} \cdot \delta \mathbf{u} \, \mathrm{d}V = \int_V \rho \mathbf{b} \cdot \delta \mathbf{u} \, \mathrm{d}V + \int_{S_t} \bar{\mathbf{t}} \cdot \delta \mathbf{u} \, \mathrm{d}S -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 2.3.1, Eq. 2.3.8 & Sec. 2.3.4, p. 33; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.1, Eq. 2.8, p. 32_ - -**Virtual Work Integral Balance** -$$ -\delta W^{\mathrm{int}} + \delta W^{\mathrm{kin}} = \delta W^{\mathrm{ext}} -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 2.3.3, pp. 32–33; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.1, Eq. 2.7, p. 32_ - -**Galerkin Discretized Weak Form** -$$ -\int_V \nabla(w^h) : \boldsymbol{\sigma}(u^h) \, \mathrm{d}V + \int_V \rho \ddot{u}^h \cdot w^h \, \mathrm{d}V - \int_V \rho \mathbf{b} \cdot w^h \, \mathrm{d}V - \int_{S_t} \bar{\mathbf{t}} \cdot w^h \, \mathrm{d}S = 0 -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 2.4.1, pp. 34–35; ME280A.pdf, Sec. 7, p. 136_ - -**Notation:** -{'\\boldsymbol{\\sigma}': 'Cauchy stress tensor.', '\\mathbf{u}': 'Displacement vector field.', '\\delta \\mathbf{u}': 'Virtual displacement test function.', '\\rho': 'Mass density.', '\\mathbf{b}': 'Body force vector.', '\\bar{\\mathbf{t}}': 'Prescribed surface traction vector.', 'S_u': 'Boundary surface with prescribed essential (Dirichlet) displacement.', 'S_t': 'Boundary surface with prescribed natural (Neumann) surface traction.'} - - -## 3. Algorithmic Implementation - -**Galerkin Weak Form Variational Derivation Procedure** -$$ -\begin{algorithmic} -\State $Start with strong form momentum balance \nabla \cdot \boldsymbol{\sigma} + \rho \mathbf{b} = \rho \ddot{\mathbf{u}} \text{ in } V$ -\State $Define trial space \mathcal{U} = \{ \mathbf{u} \in H^1(V) \mid \mathbf{u} = \bar{\mathbf{u}} \text{ on } S_u \} \text{ and test space } \mathcal{V}_0 = \{ \delta \mathbf{u} \in H^1(V) \mid \delta \mathbf{u} = \mathbf{0} \text{ on } S_u \}$ -\State $Multiply by test function \delta \mathbf{u} \in \mathcal{V}_0 \text{ and integrate over volume } V: \int_V \delta \mathbf{u} \cdot (\nabla \cdot \boldsymbol{\sigma} + \rho \mathbf{b} - \rho \ddot{\mathbf{u}}) \, \mathrm{d}V = 0$ -\State $Apply tensor identity \delta \mathbf{u} \cdot (\nabla \cdot \boldsymbol{\sigma}) = \nabla \cdot (\boldsymbol{\sigma} \cdot \delta \mathbf{u}) - \nabla(\delta \mathbf{u}) : \boldsymbol{\sigma}$ -\State $Apply Gauss divergence theorem: \int_V \nabla \cdot (\boldsymbol{\sigma} \cdot \delta \mathbf{u}) \, \mathrm{d}V = \int_{\partial V} \delta \mathbf{u} \cdot (\boldsymbol{\sigma} \cdot \mathbf{n}) \, \mathrm{d}S$ -\State $Substitute traction condition \boldsymbol{\sigma} \cdot \mathbf{n} = \bar{\mathbf{t}} \text{ on } S_t \text{ and } \delta \mathbf{u} = \mathbf{0} \text{ on } S_u$ -\Return $\int_V \nabla(\delta \mathbf{u}) : \boldsymbol{\sigma} \, \mathrm{d}V + \int_V \rho \ddot{\mathbf{u}} \cdot \delta \mathbf{u} \, \mathrm{d}V = \int_V \rho \mathbf{b} \cdot \delta \mathbf{u} \, \mathrm{d}V + \int_{S_t} \bar{\mathbf{t}} \cdot \delta \mathbf{u} \, \mathrm{d}S$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 2.3.1, pp. 28–30; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.1, pp. 31–33_ - - -## 4. Known Pitfalls - -- **Non-Zero Test Functions on Essential Boundaries**: Failing to enforce that virtual displacements or test functions \delta \mathbf{u} vanish on Dirichlet essential boundary surfaces S_u introduces uncancelled boundary integrals \int_{S_u} \delta \mathbf{u} \cdot \mathbf{t} \, \mathrm{d}S, invalidating the weak form derivation. Mitigation: Restrict test functions \delta \mathbf{u} strictly to the homogeneous space \mathcal{V}_0 with \delta \mathbf{u} = \mathbf{0} on S_u. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 2.3.1, p. 29; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 2.1, p. 32)_ -- **Inconsistent Field Smoothness in Strong vs Weak Forms**: Requiring C^1 derivative continuity in strong form equations leads to overly restrictive function spaces. The weak form reduces order-of-differentiation requirements to C^0 piecewise polynomials across element interfaces, provided inter-element derivative discontinuities are square-integrable (H^1 space). Mitigation: Select C^0 continuous finite element shape functions satisfying H^1 completeness. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 2.2.6 & 2.3.1, pp. 27–30)_ - -## References - -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- ME280A.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-composite-voxels.md b/packages/akms/src/akms/_bundled/global_nodes/fft-composite-voxels.md deleted file mode 100644 index fb7fa48..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-composite-voxels.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -id: fft-composite-voxels -title: Composite Voxel Technique -domain: fft-galerkin -subdomain: discretization -tags: -- discretization -- fft-galerkin -- homogenization -- micromechanics -- interface-treatment -- composite-voxels -- laminate -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-discretization-moulinec-suquet - type: requires - weight: 1.0 - note: Composite voxels augment the standard voxelized discretization at material interfaces -- to: fft-galerkin-basics - type: requires - weight: 0.8 - note: Technique applies within the Galerkin or collocation FFT framework on uniform grids -- to: fft-reference-medium - type: requires - weight: 0.7 - note: Hashin-Shtrikman variational origin connects composite voxels to reference medium theory -- to: fft-periodic-bc - type: requires - weight: 0.7 - note: Operates within the periodic FFT framework on regular grids -- to: fft-finite-strain - type: feeds-into - weight: 0.6 - note: Extended to finite strains for industrial-scale simulations -context_size: medium -reading_priority: full -load_with: -- fft-discretization-moulinec-suquet -- fft-galerkin-basics -content_ref: null -akms_schema: v2 ---- - -# Composite Voxel Technique - -## Summary -The composite voxel technique addresses the accuracy and resolution limitations of standard FFT-based homogenization at material interfaces by incorporating sub-voxel scale information directly into the regular grid. Instead of assigning a single material phase to each voxel, interface voxels straddling material boundaries are modeled as miniature two-phase laminates with effective stiffness computed from the sub-voxel volume fractions and the approximate interface normal vector. For finite phase contrast, the laminate mixing rule produces the most accurate results; for porous (void) voxels, Voigt averaging is preferred, and for rigid inclusions, Reuss averaging yields the best results. The technique originates from the Hashin-Shtrikman variational principle applied with voxel-wise constant polarization fields. It has been extended to finite strains, inelastic constitutive behavior (requiring discrete internal variables per phase within composite voxels), and crystal plasticity. The method enables significant grid coarsening while maintaining accuracy, making industrial-scale FFT simulations feasible. - - -## 1. Core Concept -Standard FFT-based methods assign a single material property to each voxel, creating a staircase approximation of curved material interfaces that requires very fine grids for adequate resolution. The composite voxel technique replaces this binary assignment at interface voxels with an effective stiffness derived from a two-phase rank-1 laminate model. Each composite voxel is characterized by (1) the sub-voxel volume fractions of the constituent phases and (2) an interface normal vector approximating the average geometric orientation of the material boundary within the voxel. The conceptual origin traces to Brisard and Dormieux's application of the Hashin-Shtrikman variational principle with voxel-wise constant polarization fields, which naturally produces a sub-voxel averaging rule: $(C_{N,0}(\mathbf{y}) - \mathbf{C}^0)^{-1} = \frac{1}{\text{vol}(V)} \int_V (\mathbf{C}(\mathbf{x}) - \mathbf{C}^0)^{-1}\, d\mathbf{x}$. This Hashin-Shtrikman-derived averaging brought attention to the necessity of handling sub-voxel material distributions accurately, directly triggering the development of composite voxel methods. For inelastic materials, the composite voxel introduces discrete internal variables for each phase and solves the material evolution equations on the laminate sub-structure, effectively creating a nested homogenization at the sub-voxel scale. - - -## 2. Mathematical Formulation -The composite voxel technique replaces the standard single-phase voxel assignment at material interfaces with an effective stiffness derived from laminate mixing theory. The Hashin-Shtrikman variational principle provides the theoretical foundation, yielding a natural sub-voxel averaging rule. For finite contrast, the rank-1 laminate formula gives optimal accuracy; for extreme contrasts, simpler Voigt or Reuss bounds are used. - - -**Hashin-Shtrikman sub-voxel averaging rule:** - -$$ -(\mathbf{C}_{N,0}(\mathbf{y}) - \mathbf{C}^0)^{-1} = \frac{1}{\text{vol}(V)} \int_V (\mathbf{C}(\mathbf{x}) - \mathbf{C}^0)^{-1}\, d\mathbf{x} -$$ - -where C_{N,0}(y) is the effective stiffness at voxel y, C0 is the reference stiffness, V is the voxel volume, C(x) is the local stiffness - -**Rank-1 laminate effective stiffness (most accurate for finite contrast):** - -$$ -[INSUFFICIENT SOURCE] -$$ - -where C_lam is the effective laminate stiffness, C_1 and C_2 are the phase stiffnesses, f is the volume fraction of phase 1, n is the interface normal vector. The exact formula involves the acoustic tensor N_{ik} = n_j (C_2)_{ijkl} n_l and a planar Green's operator constructed from N^{-1}. The formula is given in Kabel, Merkert, Schneider (2015) but is not reproduced in the review sources available in this notebook. - -**Voigt average (upper bound, preferred for porous voxels):** - -$$ -\mathbf{C}_{\text{Voigt}} = \sum_{\alpha} f_\alpha\, \mathbf{C}_\alpha -$$ - -where f_alpha are the sub-voxel volume fractions, C_alpha are the constituent phase stiffnesses - -**Reuss average (lower bound, preferred for rigid inclusion voxels):** - -$$ -\mathbf{C}_{\text{Reuss}}^{-1} = \sum_{\alpha} f_\alpha\, \mathbf{C}_\alpha^{-1} -$$ - -where f_alpha are the sub-voxel volume fractions, C_alpha are the constituent phase stiffnesses - -**Notation:** - -- $\mathbf{C}_{N,0}$ — Effective stiffness of a composite voxel (depends on reference medium C0) -- $\mathbf{C}^0$ — Homogeneous reference medium stiffness -- $\mathbf{C}_\alpha$ — Stiffness tensor of phase alpha -- $f_\alpha$ — Sub-voxel volume fraction of phase alpha within the composite voxel -- $\mathbf{n}$ — Approximate interface normal vector within the composite voxel -- $V$ — Volume of the voxel - - -## 3. Algorithmic Implementation -Not applicable — this is a concept and discretization technique node. The composite voxel stiffness replaces the standard single-phase stiffness in the constitutive evaluation step of any FFT solver (basic scheme, Krylov, Newton). For inelastic materials, the laminate sub-problem is solved locally within each composite voxel at each constitutive evaluation. - -## 4. Known Pitfalls -**Laminate formula fails at extreme phase contrast:** The two-phase laminate mixing rule produces the most accurate results for media with finite phase contrast but loses its accuracy advantage at extreme or infinite contrast ratios. For voxels intersecting pores (voids), Voigt averaging is more advantageous than the laminate formula. For voxels intersecting rigid inclusions, Reuss averaging yields better results. Selecting the wrong mixing rule for a given contrast regime degrades solution accuracy. - - -**Interface normal approximation error:** The laminate mixing rule requires an interface normal vector that approximates the average geometric normal between constituents within each voxel. This approximation cannot perfectly capture highly curved interfaces, complex geometries, or multiple intersecting boundaries within a single voxel. The accuracy of the composite voxel stiffness depends directly on the quality of this normal vector estimation. - - -**Inelastic extension introduces computational complexity:** Extending composite voxels to inelastic constitutive behavior requires introducing discrete internal variables for every phase within each composite voxel and solving the material evolution equations on the laminate sub-structure. This effectively creates a nested homogenization problem at the sub-voxel scale, significantly increasing the computational cost and implementation complexity of the constitutive evaluation step. - - -**Dependence on reference medium (Hashin-Shtrikman origin):** The Hashin-Shtrikman-derived averaging rule for composite voxel stiffness depends explicitly on the reference medium $\mathbf{C}^0$. While the converged solution should be independent of this choice, the effective stiffness assigned to each composite voxel changes with the reference medium, which can affect convergence behavior and intermediate iterates. This contrasts with single-phase voxels where the local stiffness is independent of the reference medium. - - -## 5. References -- Schneider (2021) — Review of nonlinear FFT-based computational homogenization, composite voxel technique -- Kabel, Merkert, Schneider (2015) — Composite voxels with laminate mixing for linear elasticity -- Kabel, Fink, Schneider (2017) — Extension of composite voxels to finite strains -- Schneider (2019) — Composite voxels for inelastic constitutive behavior with discrete internal variables - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-convergence-schemes.md b/packages/akms/src/akms/_bundled/global_nodes/fft-convergence-schemes.md deleted file mode 100644 index 76a15ce..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-convergence-schemes.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -id: fft-convergence-schemes -title: Convergence Criteria & Solver Comparison -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- fft-galerkin -- convergence -- iterative -- benchmarks -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-solver-basic-scheme - type: requires - weight: 0.8 - note: Baseline solver in convergence comparisons; convergence rate scales linearly with contrast -- to: fft-solver-krylov-cg - type: requires - weight: 0.8 - note: Conjugate gradient is the fastest linear solver in benchmarks (4 fields) -- to: fft-solver-eyre-milton - type: requires - weight: 0.8 - note: Eyre-Milton achieves sqrt(kappa) scaling, fastest method to moderate tolerance -- to: fft-solver-polarization-admm - type: requires - weight: 0.7 - note: ADMM requires dual convergence criteria (compatibility + constitutive) -- to: fft-solver-barzilai-borwein - type: requires - weight: 0.7 - note: BB shows non-monotone residual but competitive iteration counts (2 fields) -- to: fft-solver-fast-gradient - type: requires - weight: 0.7 - note: Nesterov-type methods converge linearly with momentum-based acceleration -- to: fft-solver-newton-krylov - type: requires - weight: 0.7 - note: Newton-CG is optimal when constitutive evaluation dominates cost (8.5-12 fields) -- to: fft-solver-quasi-newton - type: requires - weight: 0.7 - note: L-BFGS/Anderson acceleration competitive at moderate tolerances (2m+2 fields) -- to: fft-green-operator - type: requires - weight: 0.6 - note: Equilibrium criterion uses the non-dimensional Green's operator in Fourier space -- to: fft-galerkin-basics - type: requires - weight: 0.5 - note: H^{-1} norm and Galerkin framework underlie the mathematically rigorous convergence criterion -context_size: large -reading_priority: full -load_with: -- fft-solver-basic-scheme -- fft-solver-eyre-milton -- fft-solver-krylov-cg -content_ref: null -akms_schema: v2 ---- - -# Convergence Criteria & Solver Comparison - -## Summary -This node consolidates convergence criteria formulas and a comparative overview of FFT-based solver performance. Three principal convergence measures are used across solver families. (1) The equilibrium criterion $\|\text{div}\,\boldsymbol{\sigma}\|_{H^{-1}_\#} \leq \text{tol}\,\|\langle\boldsymbol{\sigma}\rangle\|$ is computed in Fourier space as $\|\boldsymbol{\Gamma} \colon \boldsymbol{\sigma}\|_{L^2}$ and applies to gradient-based and Krylov solvers. (2) For polarization/ADMM schemes, the compatibility criterion $\|\boldsymbol{\varepsilon} - \mathbf{e}\|_{L^2}/\|\boldsymbol{\varepsilon}\| < \text{tol}$ and the constitutive criterion $\|\mathbb{C}\colon\boldsymbol{\varepsilon} - \lambda\|_{L^2}/\|\mathbb{C}^0\colon\boldsymbol{\varepsilon}\| < \text{tol}$ are used jointly. (3) Eyre-Milton monitors the polarization change $\|P_{k+1} - P_k\|/\|P_{k+1}\| < \text{tol}$. A benchmark on a porous bound-sand microstructure (40.14% porosity, 1% uniaxial extension, tolerance $10^{-5}$) establishes the relative performance: CG is fastest overall, BB and nonlinear CG are close seconds, Eyre-Milton and Anderson are fastest to moderate tolerance, the basic scheme fails to converge within 1000 iterations, and Newton-CG is preferred when constitutive evaluation is expensive. - - -## 1. Core Concept -Convergence assessment for FFT solvers requires criteria that match the solver structure. Gradient-based solvers (basic scheme, BB, fast gradient, nonlinear CG) produce compatible strain iterates, so checking equilibrium ($\text{div}\,\sigma = 0$) via the $H^{-1}$ norm suffices. Polarization/ADMM solvers produce iterates that are neither compatible nor in equilibrium during iteration, necessitating both a compatibility criterion (primal gap) and a constitutive criterion (dual gap). Solver comparison depends on the combined metric of iterations, FFT evaluations per iteration, and memory footprint. The iteration count alone is misleading since some methods (Newton-CG) require inner Krylov iterations with their own FFT calls. Memory footprint ranges from 1 field (basic scheme) to 12 fields (Newton-CG), creating a fundamental speed-memory tradeoff. The scaling of iteration count with the material contrast ratio $\kappa = \alpha_+/\alpha_-$ is the key theoretical differentiator: linear scaling ($\kappa$) for the basic scheme, square-root scaling ($\sqrt{\kappa}$) for CG, Eyre-Milton, and BB. - - -## 2. Mathematical Formulation -The equilibrium residual is most rigorously measured in the $H^{-1}$ norm, which corresponds to applying the non-dimensional Green's operator to the stress in Fourier space. This is the natural dual norm to the $H^1$ displacement space. An alternative $L^2$-based criterion is sometimes used but introduces a mesh-dependent prefactor. For ADMM schemes, both primal feasibility (compatibility gap) and dual feasibility (constitutive gap) must be below tolerance. - - -**Equilibrium criterion (H^{-1} norm):** - -$$ -\|\text{div}\,\boldsymbol{\sigma}\|_{H^{-1}_\#} = \|\boldsymbol{\Gamma} \colon \boldsymbol{\sigma}\|_{L^2} \leq \text{tol} \cdot \|\langle\boldsymbol{\sigma}\rangle\| -$$ - -where Gamma is the non-dimensional Green's operator; angle brackets denote volume average - -**Equilibrium criterion (L^2 variant):** - -$$ -\|\text{div}\,\boldsymbol{\sigma}\|_{L^2} \leq \frac{\sqrt{2\pi}}{L}\,\text{tol}\,\|\langle\boldsymbol{\sigma}\rangle\| -$$ - -where L is the unit cell size; the prefactor sqrt(2pi)/L introduces mesh dependence - -**Compatibility criterion (ADMM/polarization):** - -$$ -\frac{\|\boldsymbol{\varepsilon}_{k+1} - \mathbf{e}_{k+1}\|_{L^2}}{\|\boldsymbol{\varepsilon}\|_{L^2}} < \text{tol} -$$ - -where epsilon is the compatible strain, e is the auxiliary strain; primal feasibility gap - -**Constitutive criterion (ADMM/polarization):** - -$$ -\frac{\|\mathbb{C}(\mathbf{x}) \colon \boldsymbol{\varepsilon}_{k+1} - \lambda_{k+1}\|_{L^2}}{\|\mathbb{C}^0 \colon \boldsymbol{\varepsilon}\|_{L^2}} < \text{tol} -$$ - -where lambda is the Lagrange multiplier converging to stress; dual feasibility gap - -**Polarization change criterion (Eyre-Milton):** - -$$ -\frac{\|P_{k+1} - P_k\|_{L^2}}{\|P_{k+1}\|_{L^2}} < \text{tol} -$$ - -where P is the polarization field; natural convergence measure for the Eyre-Milton scheme - -**Contrast ratio scaling summary:** - -$$ -\text{Basic scheme}\colon O(\kappa), \quad \text{CG / Eyre-Milton / BB}\colon O(\sqrt{\kappa}), \quad \text{Newton}\colon O(\log \kappa) -$$ - -where kappa = alpha_+/alpha_- is the material contrast; Newton scaling reflects quadratic inner convergence - -**Notation:** - -- $\boldsymbol{\Gamma}$ — Non-dimensional Green's operator -- $\|\cdot\|_{H^{-1}_\#}$ — H^{-1} dual norm on the periodic unit cell -- $\boldsymbol{\varepsilon}$ — Compatible strain field -- $\mathbf{e}$ — Auxiliary strain field (ADMM) -- $\lambda$ — Lagrange multiplier / stress (ADMM) -- $P$ — Polarization field (Eyre-Milton) -- $\kappa$ — Material contrast ratio alpha_+/alpha_- - - -## 3. Algorithmic Implementation -This node collects convergence criteria and benchmark data rather than defining a single algorithm. -Solver comparison (porous bound-sand, 40.14% porosity, 1% uniaxial, tol = 1e-5): - Basic scheme: >1000 iterations (did not converge), 1 field - Fast gradient (Nesterov): converges but lags behind fastest methods, 2 fields - Barzilai-Borwein: competitive with CG, non-monotone residual, 2 fields - Nonlinear CG (FR): close to CG performance, 3 fields - Linear CG: fastest overall iteration count, 4 fields - Anderson (m=4): second fastest to tol=1e-3, slows for tighter tol, 10 fields - Eyre-Milton: fastest to tol=1e-3, 2 fields - ADMM: slightly slower than Eyre-Milton, 3 fields - Newton-CG: best when constitutive law is expensive, 8.5-12 fields + tangent - - -## 4. Known Pitfalls -**Mixing convergence criteria across solver families:** The equilibrium criterion ($\|\Gamma \colon \sigma\|$) applies to gradient and Krylov solvers but is not directly computable for ADMM iterates, which are not in equilibrium until convergence. Comparing iteration counts at the same nominal tolerance across different criteria can be misleading. Always use the native criterion for each solver and verify with a common post-convergence check. - - -**L^2 equilibrium criterion is mesh-dependent:** The $L^2$ norm of $\text{div}\,\sigma$ depends on the mesh through the factor $\sqrt{2\pi}/L$, while the $H^{-1}$ norm is mesh-independent. Using the $L^2$ criterion without the scaling factor can lead to false convergence declarations on coarse meshes and overly strict tolerances on fine meshes. - - -**Non-monotone residuals in spectral methods:** The Barzilai-Borwein and Anderson acceleration methods exhibit non-monotone residual histories where the residual can temporarily increase. Monitoring convergence with strict monotonic decrease tests will incorrectly diagnose these methods as diverging. Use a running minimum or averaged residual instead. - - -**Memory footprint dominates for large 3D problems:** On a $512^3$ grid with 6-component symmetric tensors in double precision, each field requires approximately 6 GB. The difference between 2 fields (Eyre-Milton, 12 GB) and 12 fields (Newton-CG, 72 GB) can determine whether a problem fits in GPU memory. Memory constraints often override iteration-count advantages. - - -**Iteration count alone is insufficient for cost comparison:** Newton-CG may require only a few outer iterations but each contains many inner CG iterations with FFT evaluations. The total number of FFT calls (proportional to wall-clock time) is a better cost metric. Similarly, methods requiring local nonlinear solves (ADMM, Eyre-Milton) have higher per-iteration cost than gradient methods that only evaluate the forward constitutive law. - - -## 5. References -- Schneider (2021) -- review of nonlinear FFT-based computational homogenization, convergence criteria and solver comparison Table 4 -- Lucarini et al. (2022) -- convergence criteria for FFT-based solvers, equilibrium and compatibility norms - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-coupled-problems.md b/packages/akms/src/akms/_bundled/global_nodes/fft-coupled-problems.md deleted file mode 100644 index 3ffa855..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-coupled-problems.md +++ /dev/null @@ -1,203 +0,0 @@ ---- -id: fft-coupled-problems -title: FFT for Coupled & Multi-Physics Problems -domain: fft-galerkin -subdomain: coupled-problems -tags: -- fft-galerkin -- homogenization -- spectral -- continuum-mechanics -- multi-physics -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Coupled problems extend the Lippmann-Schwinger framework with additional polarization terms -- to: fft-green-operator - type: requires - weight: 0.8 - note: Green's operator used in the mechanical sub-problem of coupled systems -- to: fft-galerkin-basics - type: requires - weight: 0.9 - note: FFT framework provides the spectral solver infrastructure -- to: fft-solver-basic-scheme - type: feeds-into - weight: 0.6 - note: Basic scheme or ADMM can solve the primal non-symmetric piezoelectric formulation -- to: fft-phase-field - type: feeds-into - weight: 0.7 - note: Phase-field fracture is a specific instance of coupled multi-physics with FFT -- to: fft-reference-medium - type: requires - weight: 0.7 - note: Reference medium selection affects convergence of the mechanical sub-problem -context_size: large -reading_priority: full -load_with: -- fft-lippmann-schwinger -- fft-galerkin-basics -content_ref: null -akms_schema: v2 ---- - -# FFT for Coupled & Multi-Physics Problems - -## Summary -FFT-based methods extend to coupled multi-physics problems where mechanical response interacts with thermal, electrical, magnetic, or chemical fields. The general approach uses staggered algorithms that sequentially solve the mechanical and auxiliary field sub-problems at each load step. For thermo-mechanical coupling, the thermal strain enters as an eigenstrain in the stress polarization tensor $\boldsymbol{\tau} = (\mathbf{C} - \mathbf{C}_0) : \boldsymbol{\varepsilon} - \boldsymbol{\beta}(T - T_{\mathrm{ref}})$. For piezoelectricity, three formulations exist: (1) primal (non-symmetric, solvable by basic scheme/ADMM), (2) indefinite symmetric (requires MINRES, high memory), and (3) partial Legendre-Fenchel transform (symmetric positive-definite, solvable by CG, lowest memory). Applications span conductivity/diffusivity, thermo-mechanics, piezoelectricity, ferroelectrics, electro-chemo-mechanical coupling in batteries, and phase-field recrystallization. - - -## 1. Core Concept -The FFT homogenization framework is highly versatile for multi-physics problems because the Lippmann-Schwinger structure naturally accommodates additional fields through modified polarization tensors or augmented constitutive operators. In the simplest case (thermo-mechanical coupling), the temperature field enters the mechanical equilibrium as a thermal eigenstrain added to the stress polarization. For fully coupled electro-mechanical problems (piezoelectricity), the constitutive law links stress $\boldsymbol{\sigma}$ and electric induction $\mathbf{D}$ to strain $\boldsymbol{\varepsilon}$ and electric field $\mathbf{E}$ through the elastic stiffness $\mathbf{C}$, piezoelectric moduli $\mathbf{e}$, and dielectric permittivity $\boldsymbol{\gamma}$. The mathematical structure of the coupled operator matrix (symmetric vs. non-symmetric, definite vs. indefinite) determines which FFT solver can be used, creating fundamental trade-offs between solver efficiency and memory. - - -## 2. Mathematical Formulation -Multi-physics FFT problems modify the standard Lippmann-Schwinger framework by either adding eigenstrain contributions to the polarization tensor (weak coupling) or by augmenting the constitutive operator to a block matrix system (strong coupling). For thermo-mechanical coupling, the standard approach treats temperature as a prescribed input field via the eigenstrain method, modifying only the stress polarization. When the temperature field itself must be computed (steady-state heat conduction), the scalar Lippmann-Schwinger equation with a second-order Green's operator is used — mathematically analogous to the conductivity problem. For strongly coupled problems like piezoelectricity, the constitutive operator becomes a block matrix and the corresponding Green's operator in Fourier space is block diagonal, combining the fourth-order mechanical Green's operator and the second-order scalar (electric/dielectric) Green's operator. The choice of mathematical formulation for the coupled operator has profound consequences for solver selection: the primal form is non-symmetric, the negated form is symmetric indefinite, and the Legendre-Fenchel transform yields symmetric positive-definite operators enabling CG. - - -**Thermo-mechanical stress polarization with thermal eigenstrain:** - -$$ -\boldsymbol{\tau} = (\mathbf{C} - \mathbf{C}_0) : \boldsymbol{\varepsilon} - \boldsymbol{\beta}(T - T_{\mathrm{ref}}) -$$ - -where C is local elastic stiffness, C_0 is reference stiffness, beta is the thermal moduli tensor, T is local temperature, T_ref is the reference temperature - -**Piezoelectric constitutive equations:** - -$$ -\boldsymbol{\sigma} = \mathbf{C} : \boldsymbol{\varepsilon} - \mathbf{e}^T \cdot \mathbf{E}, \quad \mathbf{D} = \mathbf{e} : \boldsymbol{\varepsilon} + \boldsymbol{\gamma} \cdot \mathbf{E} -$$ - -where sigma is stress, D is electric induction, e is the piezoelectric moduli tensor, gamma is the dielectric permittivity tensor, E is the electric field - -**Primal formulation (non-symmetric):** - -$$ -\begin{bmatrix} \boldsymbol{\sigma} \\ \mathbf{D} \end{bmatrix} = \begin{bmatrix} \mathbf{C} & -\mathbf{e}^T \\ \mathbf{e} & \boldsymbol{\gamma} \end{bmatrix} \begin{bmatrix} \boldsymbol{\varepsilon} \\ \mathbf{E} \end{bmatrix} -$$ - -where Non-symmetric operator; solvable by basic scheme or ADMM - -**Indefinite symmetric formulation:** - -$$ -\begin{bmatrix} \boldsymbol{\sigma} \\ -\mathbf{D} \end{bmatrix} = \begin{bmatrix} \mathbf{C} & -\mathbf{e}^T \\ -\mathbf{e} & -\boldsymbol{\gamma} \end{bmatrix} \begin{bmatrix} \boldsymbol{\varepsilon} \\ \mathbf{E} \end{bmatrix} -$$ - -where Symmetric but indefinite; requires MINRES with high memory cost - -**Partial Legendre-Fenchel formulation (symmetric positive-definite):** - -$$ -\begin{bmatrix} \boldsymbol{\sigma} \\ \mathbf{E} \end{bmatrix} = \begin{bmatrix} \mathbf{C} + \mathbf{e}^T \cdot \boldsymbol{\gamma}^{-1} \cdot \mathbf{e} & -\mathbf{e}^T \cdot \boldsymbol{\gamma}^{-1} \\ -\boldsymbol{\gamma}^{-1} \cdot \mathbf{e} & \boldsymbol{\gamma}^{-1} \end{bmatrix} \begin{bmatrix} \boldsymbol{\varepsilon} \\ \mathbf{D} \end{bmatrix} -$$ - -where Eliminates D as independent variable; symmetric positive-definite operator solvable by CG with lowest memory - -**Augmented Lippmann-Schwinger equation for SPD piezoelectric formulation:** - -$$ -\begin{bmatrix} \hat{\boldsymbol{\varepsilon}}(\boldsymbol{\xi}) \\ \hat{\mathbf{D}}(\boldsymbol{\xi}) \end{bmatrix} = \begin{bmatrix} \bar{\boldsymbol{\varepsilon}} \\ \bar{\mathbf{D}} \end{bmatrix} - \begin{bmatrix} \hat{\boldsymbol{\Gamma}}^0_{\mathrm{mech}}(\boldsymbol{\xi}) & \mathbf{0} \\ \mathbf{0} & \hat{\boldsymbol{\Gamma}}^0_{\mathrm{elec}}(\boldsymbol{\xi}) \end{bmatrix} \begin{bmatrix} \hat{\boldsymbol{\tau}}_{\mathrm{mech}}(\boldsymbol{\xi}) \\ \hat{\boldsymbol{\tau}}_{\mathrm{elec}}(\boldsymbol{\xi}) \end{bmatrix} -$$ - -where The block diagonal Green's operator decouples in Fourier space: Gamma^0_mech is the standard fourth-order mechanical Green's operator, Gamma^0_elec is the second-order scalar Green's operator for the electric potential. tau_mech and tau_elec are the mechanical and electric polarization tensors computed from the SPD constitutive operator and the respective reference operators. The off-diagonal zeros arise because the differential constraints (mechanical equilibrium and Gauss's law) are independent in Fourier space. - -**Scalar Green's operator for the electric/thermal sub-problem:** - -$$ -\hat{\boldsymbol{\Gamma}}^0_{\mathrm{elec}}(\boldsymbol{\xi}) = \frac{1}{\gamma_0 |\boldsymbol{\xi}|^2} \boldsymbol{\xi} \otimes \boldsymbol{\xi}, \quad \boldsymbol{\xi} \neq \mathbf{0} -$$ - -where gamma_0 is the reference dielectric permittivity (scalar, for isotropic reference), xi is the frequency vector. This second-order tensor operates on vectors, in contrast to the fourth-order mechanical Green's operator that operates on second-order tensors. - -**Conductivity/thermal Lippmann-Schwinger equation:** - -$$ -\hat{\mathbf{E}}(\boldsymbol{\xi}) = \bar{\mathbf{E}} - \hat{\boldsymbol{\Gamma}}^0_{\mathrm{th}}(\boldsymbol{\xi}) \cdot \hat{\mathbf{p}}(\boldsymbol{\xi}), \quad \mathbf{p}(\mathbf{x}) = (\boldsymbol{\kappa}(\mathbf{x}) - \boldsymbol{\kappa}_0) \cdot \mathbf{E}(\mathbf{x}) -$$ - -where E = -nabla T is the temperature gradient vector, E_bar is the macroscopic temperature gradient, p is the thermal/conductivity polarization vector, kappa is the local thermal conductivity tensor, kappa_0 is the reference conductivity. Gamma^0_th has the same structure as Gamma^0_elec with kappa_0 replacing gamma_0. - -**Notation:** - -- $\boldsymbol{\tau}$ — Stress polarization tensor (modified for multi-physics) -- $\boldsymbol{\beta}$ — Second-order thermal moduli tensor -- $\mathbf{e}$ — Third-order piezoelectric moduli tensor -- $\boldsymbol{\gamma}$ — Second-order dielectric permittivity tensor -- $\mathbf{D}$ — Electric induction (electric displacement) vector -- $\mathbf{E}$ — Electric field vector (or temperature gradient vector in thermal context) -- $\hat{\boldsymbol{\Gamma}}^0_{\mathrm{mech}}$ — Fourth-order mechanical Green's operator in Fourier space -- $\hat{\boldsymbol{\Gamma}}^0_{\mathrm{elec}}$ — Second-order scalar Green's operator for the electric potential in Fourier space -- $\hat{\boldsymbol{\Gamma}}^0_{\mathrm{th}}$ — Second-order scalar Green's operator for thermal conductivity in Fourier space -- $\boldsymbol{\kappa}$ — Second-order thermal conductivity tensor -- $\boldsymbol{\kappa}_0$ — Reference thermal conductivity (scalar for isotropic reference) -- $\gamma_0$ — Reference dielectric permittivity (scalar for isotropic reference) -- $\mathbf{p}$ — Thermal/conductivity polarization vector - - -## 3. Algorithmic Implementation -**Algorithm: Staggered Algorithm for Thermo-Mechanical Coupling** - -$$ -\begin{algorithmic} -\State $Initialize \colon \boldsymbol{\varepsilon}_0(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}}, \; T(\mathbf{x}) = T_{\mathrm{ref}} + \Delta T(\mathbf{x})$ -\For{$\text{each load/time step } n = 1, 2, \ldots$} - \State $\text{Step 1a (eigenstrain approach)} \colon T(\mathbf{x}) \gets \text{prescribed temperature field (uniform } \Delta T \text{ or heterogeneous input)}$ - \State $\text{Step 1b (conductivity solve, optional)} \colon \hat{\mathbf{E}}(\boldsymbol{\xi}) = \bar{\mathbf{E}} - \hat{\boldsymbol{\Gamma}}^0_{\mathrm{th}}(\boldsymbol{\xi}) \cdot \hat{\mathbf{p}}(\boldsymbol{\xi}), \quad \mathbf{p}(\mathbf{x}) = (\boldsymbol{\kappa}(\mathbf{x}) - \boldsymbol{\kappa}_0) \cdot \mathbf{E}(\mathbf{x})$ - \State $\text{Step 2} \colon \boldsymbol{\tau}(\mathbf{x}) = (\mathbf{C}(\mathbf{x}) - \mathbf{C}_0) \colon \boldsymbol{\varepsilon}(\mathbf{x}) - \boldsymbol{\beta}(\mathbf{x})(T(\mathbf{x}) - T_{\mathrm{ref}})$ - \State $\text{Step 3} \colon \hat{\boldsymbol{\varepsilon}}(\boldsymbol{\xi}) = \bar{\boldsymbol{\varepsilon}} - \hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) \colon \hat{\boldsymbol{\tau}}(\boldsymbol{\xi})$ - \State $\text{Iterate Steps 2-3 until mechanical convergence}$ -\EndFor -\end{algorithmic} -$$ - -**Taichi Mapping:** -Thermal eigenstrain computation is a local per-voxel operation, embarrassingly parallel on GPU. The modified polarization adds one vector subtraction per voxel. The conductivity solve (Step 1b) uses the same FFT infrastructure as the mechanical solve but with a second-order (not fourth-order) Green's operator, reducing memory. The mechanical solver uses the same FFT infrastructure as the isothermal case. - -**Algorithm: Piezoelectric Coupling via Legendre-Fenchel Formulation** - -$$ -\begin{algorithmic} -\State $Initialize \colon \boldsymbol{\varepsilon}_0 = \bar{\boldsymbol{\varepsilon}}, \; \mathbf{D}_0 = \bar{\mathbf{D}}$ -\State $\text{Precompute reference operators} \colon \hat{\boldsymbol{\Gamma}}^0_{\mathrm{mech}}(\boldsymbol{\xi}) = \xi_l \xi_j [C^0_{ijkl} \xi_l \xi_j]^{-1}, \quad \hat{\boldsymbol{\Gamma}}^0_{\mathrm{elec}}(\boldsymbol{\xi}) = \frac{1}{\gamma_0 |\boldsymbol{\xi}|^2} \boldsymbol{\xi} \otimes \boldsymbol{\xi}$ -\State $\text{Compute transformed SPD constitutive operator per voxel} \colon \mathbf{L}^{*}(\mathbf{x}) = \begin{bmatrix} \mathbf{C} + \mathbf{e}^T \boldsymbol{\gamma}^{-1} \mathbf{e} & -\mathbf{e}^T \boldsymbol{\gamma}^{-1} \\ -\boldsymbol{\gamma}^{-1} \mathbf{e} & \boldsymbol{\gamma}^{-1} \end{bmatrix}$ -\While{$\text{residual} > \mathrm{tol}$} - \State $\begin{bmatrix} \boldsymbol{\sigma} \\ \mathbf{E} \end{bmatrix} = \mathbf{L}^{*}(\mathbf{x}) \begin{bmatrix} \boldsymbol{\varepsilon} \\ \mathbf{D} \end{bmatrix}$ - \State $\text{Compute augmented polarization} \colon \begin{bmatrix} \hat{\boldsymbol{\tau}}_{\mathrm{mech}} \\ \hat{\boldsymbol{\tau}}_{\mathrm{elec}} \end{bmatrix} = \begin{bmatrix} \hat{\boldsymbol{\sigma}} - \mathbf{L}^{*,0}_{\mathrm{mech}} \colon \hat{\boldsymbol{\varepsilon}} \\ \hat{\mathbf{E}} - \mathbf{L}^{*,0}_{\mathrm{elec}} \cdot \hat{\mathbf{D}} \end{bmatrix}$ - \State $\text{Update fields via block Green's operator} \colon \begin{bmatrix} \hat{\boldsymbol{\varepsilon}} \\ \hat{\mathbf{D}} \end{bmatrix} \gets \begin{bmatrix} \bar{\boldsymbol{\varepsilon}} \\ \bar{\mathbf{D}} \end{bmatrix} - \begin{bmatrix} \hat{\boldsymbol{\Gamma}}^0_{\mathrm{mech}} & \mathbf{0} \\ \mathbf{0} & \hat{\boldsymbol{\Gamma}}^0_{\mathrm{elec}} \end{bmatrix} \begin{bmatrix} \hat{\boldsymbol{\tau}}_{\mathrm{mech}} \\ \hat{\boldsymbol{\tau}}_{\mathrm{elec}} \end{bmatrix}$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -Per-voxel constitutive evaluation of the block operator is embarrassingly parallel. The block Green's operator is applied as two independent FFT operations: one for the mechanical strain (6 components) and one for the electric displacement (3 components). CG iterations use standard FFT pairs. Memory per voxel: 6 strain + 6 stress + 3 D + 3 E components plus the block constitutive matrix entries. - - -## 4. Known Pitfalls -**Non-symmetric primal formulation prevents CG:** The direct (primal) piezoelectric constitutive matrix is non-symmetric because $\mathbf{e}$ and $-\mathbf{e}^T$ appear in off-diagonal positions. CG requires symmetry, so the primal form forces use of the basic scheme or ADMM, which converge slower than Krylov solvers. - - -**MINRES memory overhead for indefinite formulation:** The indefinite symmetric formulation preserves the conditioning of the primal form but requires MINRES, which has a comparatively high memory demand. This acts as a severe limitation for high-resolution 3D microstructures. - - -**Spectral shift in Legendre-Fenchel formulation:** The partial Legendre-Fenchel transformation alters the spectrum of the linear operator compared to the primal formulation. While the resulting operator is symmetric positive-definite (allowing CG), the spectral shift can affect the convergence rate of iterative solvers, potentially requiring more iterations than expected. - - -**Operator splitting errors in staggered schemes:** Staggered algorithms decouple the multi-physics fields and solve them sequentially. This operator splitting introduces temporal integration errors (typically first or second order), which can lead to artificial dissipation or reduced accuracy in strongly coupled regimes. Sufficient staggered iterations or small time steps are needed. - - -**Memory inflation from multiple field storage:** Multi-physics problems require simultaneous storage of multiple vector and tensor fields (displacement, electric displacement, electric field, polarization, temperature). For high-resolution 3D microstructures, this memory overhead can become the practical bottleneck, especially when combined with tangent storage for Newton-type solvers. - - -## 5. References -- Schneider (2021) -- Coupled problems framework, conductivity, thermo-mechanics, piezoelectricity -- Brenner (2009) -- Thermo-mechanical eigenstrain approach, accelerated polarization schemes -- Wicht et al. (2020) -- Piezoelectric formulations, primal vs Legendre-Fenchel comparison -- Lucarini et al. (2022) -- Multi-physics FFT overview, staggered algorithms - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-fd-highorder.md b/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-fd-highorder.md deleted file mode 100644 index 2704a5d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-fd-highorder.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -id: fft-discretization-fd-highorder -title: Higher-Order Finite Difference Schemes -domain: fft-galerkin -subdomain: discretization-schemes -tags: -- discretization -- finite-difference -- fft-galerkin -- spectral -- homogenization -- convergence -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-discretization-moulinec-suquet - type: refines - weight: 1.0 - note: Higher-order FD replaces continuous frequency with trigonometric approximations of increasing order -- to: fft-green-operator - type: requires - weight: 0.9 - note: Modified frequency vectors are substituted into the Green's operator formula -- to: fft-freq-grid - type: requires - weight: 0.8 - note: Frequency vector modifications operate on the discrete frequency grid -- to: fft-discretization-staggered - type: refines - weight: 0.6 - note: Both are finite difference alternatives to Moulinec-Suquet; staggered grid converges where high-order FD fails for - porous media -- to: fft-discretization-willot - type: refines - weight: 0.6 - note: Willot's rotated staggered grid is another FD scheme; high-order CD lacks discrete combinatorial consistency that - Willot provides -context_size: medium -reading_priority: full -load_with: -- fft-discretization-moulinec-suquet -- fft-green-operator -content_ref: null -akms_schema: v2 ---- - -# Higher-Order Finite Difference Schemes - -## Summary -Higher-order finite difference schemes replace continuous spatial derivatives in the FFT-based homogenization framework with central difference approximations of increasing order (2nd, 4th, 12th). Each order produces a modified purely imaginary frequency vector involving weighted sums of sine functions. These schemes excel for smooth microstructures without material property jumps (e.g., non-convex energy minimization), but suffer from oscillatory artifacts at sharp interfaces that worsen with increasing order. For porous materials with infinite contrast, higher-order schemes fail to converge entirely. - - -## 1. Core Concept -The core idea, introduced by Mueller (1998), is to replace the continuous spatial derivative in the Green's operator with central finite difference approximations on the regular voxel grid. Homogeneous finite difference stencils produce Fourier multipliers upon discrete Fourier transformation, so the modification amounts to replacing the continuous frequency vector $2\pi\xi_j/L_j$ with a trigonometric expression involving $\sin(2\pi\xi_j/N_j)$ and its harmonics. Higher-order stencils use longer-range neighbors to achieve better approximation of the derivative for smooth fields. However, these schemes lack discrete combinatorial consistency, meaning they do not preserve the exact algebraic structure of the underlying differential operators on the discrete grid. This deficiency makes them unsuitable for problems with large phase contrast, where oscillatory artifacts propagate away from interfaces and intensify with increasing order. - - -## 2. Mathematical Formulation -Each higher-order central difference scheme defines a modified frequency vector $k_j$ that replaces the continuous frequency in the Green's operator. All central difference schemes produce purely imaginary frequency vectors (unlike the staggered grid which yields a general complex vector). The Green's operator is then applied using the standard algebraic sequence with the normalized frequency vector $\boldsymbol{\eta} = \mathbf{k}/\|\mathbf{k}\|$. - - -**2nd-order central difference frequency vector:** - -$$ -k_j = i \sin\!\left(\frac{2\pi \xi_j}{N_j}\right) \frac{N_j}{L_j} -$$ - -where xi_j is the integer frequency index, N_j the number of voxels, L_j the cell dimension in direction j - -**4th-order central difference frequency vector:** - -$$ -k_j = i \left[ 8 \sin\!\left(\frac{2\pi \xi_j}{N_j}\right) - \sin\!\left(\frac{4\pi \xi_j}{N_j}\right) \right] \frac{N_j}{L_j} -$$ - -where The coefficients 8 and -1 arise from the 4th-order central difference stencil (a global scaling factor of 1/6 is absorbed into the expression) - -**12th-order central difference frequency vector:** - -$$ -k_j = i \left[ 23760 \sin\!\left(\frac{2\pi \xi_j}{N_j}\right) - 7425 \sin\!\left(\frac{4\pi \xi_j}{N_j}\right) + 2200 \sin\!\left(\frac{6\pi \xi_j}{N_j}\right) - 495 \sin\!\left(\frac{8\pi \xi_j}{N_j}\right) + 72 \sin\!\left(\frac{10\pi \xi_j}{N_j}\right) - 5 \sin\!\left(\frac{12\pi \xi_j}{N_j}\right) \right] \frac{N_j}{L_j} -$$ - -where The coefficients arise from the 12th-order central difference stencil (a global scaling factor of 1/27720 is absorbed) - -**Comparison with other discretization frequency vectors:** - -$$ -k_j^{\text{MS}} = \frac{2\pi \xi_j}{L_j}, \quad k_j^{\text{Willot}} = \prod_{k \neq j}\left(e^{2\pi i \xi_k/N_k} + 1\right)\left(e^{2\pi i \xi_j/N_j} - 1\right)\frac{N_j}{L_j}, \quad k_j^{\text{stag}} = \left(e^{-2\pi i \xi_j/N_j} - 1\right)\frac{N_j}{L_j} -$$ - -where MS = Moulinec-Suquet (continuous), Willot = rotated staggered grid, stag = standard staggered grid - -**Green's operator application (common to all non-staggered FD schemes):** - -$$ -\boldsymbol{\eta} = \frac{\mathbf{k}}{\|\mathbf{k}\|}, \quad \mathbf{f} = \hat{\boldsymbol{\tau}}(\boldsymbol{\xi}) \bar{\boldsymbol{\eta}}, \quad s = \mathbf{f} \cdot \bar{\boldsymbol{\eta}}, \quad \mathbf{u} = \frac{-\mathbf{f} + s\,\bar{\boldsymbol{\eta}}/2}{\mu_0} -$$ - -where bar{eta} is the complex conjugate of the normalized frequency vector, mu_0 the reference shear modulus - -**Notation:** - -- $k_j$ — Modified frequency vector component for the chosen FD scheme -- $\boldsymbol{\eta}$ — Normalized modified frequency vector -- $\bar{\boldsymbol{\eta}}$ — Complex conjugate of the normalized frequency vector -- $i$ — Imaginary unit -- $N_j$ — Number of voxels in direction j -- $L_j$ — Cell dimension in direction j -- $\xi_j$ — Integer frequency index in direction j - - -## 3. Algorithmic Implementation -Not applicable as a standalone algorithm. Higher-order FD schemes only modify the frequency vector computation within the Green's operator application loop. The modified k_j is substituted into the same algebraic sequence used by the Moulinec-Suquet or other discretization schemes (see fft-green-operator and fft-discretization-moulinec-suquet). - -## 4. Known Pitfalls -**Oscillatory artifacts at material interfaces:** At sharp material interfaces, higher-order central difference schemes produce oscillatory stress and strain fields that propagate away from the interface into the bulk material. The severity of these oscillations increases with the order of the scheme. This is a direct consequence of the lack of discrete combinatorial consistency in these discretizations. - - -**Failure for porous materials (infinite contrast):** For highly porous microstructures (e.g., bound sand with approximately 40% porosity), higher-order FD schemes fail to converge entirely. The Krylov solver residual decreases initially but then stalls, similar to the continuous Moulinec-Suquet discretization. In benchmark tests, only the staggered grid and 2nd-order central differences achieved convergence for such microstructures. - - -**Suitability restricted to small phase contrast:** Due to the lack of discrete combinatorial consistency, higher-order FD schemes are primarily suitable for problems with small contrast between phases. They excel for smooth microstructures without material property jumps (e.g., arising from non-convex energy minimization) but should not be used for high-contrast composites. - - -**Absorbed scaling factors in frequency vector expressions:** The standard algorithmic summary absorbs global scaling factors (1/6 for 4th-order, 1/27720 for 12th-order) into the frequency vector coefficients. If these are not consistently handled, the effective stiffness scaling will be incorrect. The absorbed form is convenient for implementation but obscures the connection to the underlying finite difference stencil weights. - - -## 5. References -- Schneider (2021) — Review of nonlinear FFT-based computational homogenization, higher-order finite difference discretizations -- Mueller (1998) — Original proposal for replacing continuous derivatives with finite differences in FFT homogenization -- Berbenni, Taupin, Djaka, Fressengeas (2018) — 2nd-order central difference scheme for spectral elasto-static problems - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-fem.md b/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-fem.md deleted file mode 100644 index 4051370..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-fem.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: fft-discretization-fem -title: FEM-Based FFT (Hex Elements & FANS) -domain: fft-galerkin -subdomain: discretization-schemes -tags: -- discretization -- fft-galerkin -- spectral -- homogenization -- convergence -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-discretization-willot - type: refines - weight: 1.0 - note: Willot's scheme is equivalent to trilinear FEM with reduced integration (1 Gauss point); full FEM uses 8 Gauss points -- to: fft-green-operator - type: requires - weight: 0.9 - note: FEM discretization produces a semi-explicit Green's operator requiring 3x3 Hermitian matrix inversion -- to: fft-lippmann-schwinger - type: feeds-into - weight: 0.9 - note: Lippmann-Schwinger equation and solvers are constructed for the FEM-discretized system -- to: fft-convergence-schemes - type: feeds-into - weight: 0.7 - note: FANS uses Newton-Krylov solver for the FEM-discretized nonlinear system -- to: fft-discretization-staggered - type: refines - weight: 0.5 - note: Both use sub-grids separating displacement and strain evaluation points; FEM uses 8 Gauss points vs staggered grid's - voxel-center evaluation -context_size: large -reading_priority: full -load_with: -- fft-discretization-willot -- fft-green-operator -- fft-lippmann-schwinger -content_ref: null -akms_schema: v2 ---- - -# FEM-Based FFT (Hex Elements & FANS) - -## Summary -The FEM-based FFT approach uses trilinear hexahedral finite elements on the regular periodic voxel grid, with nodal displacements at voxel corners and strain/stress evaluation at 8 Gauss points per element. Since FEM stencils on regular meshes can be interpreted as specific finite difference stencils, they produce Fourier multipliers that enable FFT-based solution. The key difference from Willot's scheme (which is equivalent to under-integrated FEM with 1 Gauss point) is that full integration with 8 Gauss points eliminates hourglass instabilities, at the cost of 8x memory and computational overhead. The FANS (Fourier-Accelerated Nodal Solver) method by Fritzen and Leuschner mitigates this cost through displacement-based formulation, sparse Newton tangent storage, and selective reduced integration. - - -## 1. Core Concept -The FEM-FFT method introduced by Schneider et al. places nodal displacement values on the nodal grid $Y^{\text{node}}_N$ (voxel corners) and introduces a Gauss-point grid $Y^{\text{Gauss}}_N$ with eight integration points per element. The discrete symmetrized gradient operator $D$ maps displacement fields from the nodal grid to strain values at the Gauss points. The crucial insight linking FEM to FFT is that FEM on regular periodic meshes yields specific finite difference stencils whose Fourier transforms are known, enabling the same FFT-based solution machinery. Willot's finite difference discretization is mathematically identical to trilinear FEM with reduced integration (one Gauss point at the voxel center). This FEM interpretation settles questions about convergence and stability: for non-porous materials only global hourglass instabilities occur (concentrated at Nyquist frequencies, fixable by zeroing the Green's operator there), but for porous materials local hourglass modes emerge that cannot be stabilized. Full 8-point integration eliminates these instabilities entirely. - - -## 2. Mathematical Formulation -The FEM variational principle minimizes the total discrete energy over all admissible displacement fluctuation fields on the nodal grid. The discrete symmetrized gradient $D$ maps nodal displacements to Gauss-point strains. The resulting Euler-Lagrange equations can be reformulated as a Lippmann-Schwinger equation, but the discrete Green's operator requires inverting a Hermitian $3 \times 3$ matrix at each frequency point (semi-explicit operator), unlike the fully explicit operators of finite difference schemes. - - -**FEM variational principle on the voxel grid:** - -$$ -\sum_{\mathbf{x} \in Y^{\text{Gauss}}_N} w\!\left(\mathbf{x},\, \bar{\boldsymbol{\varepsilon}} + D\mathbf{u}_N(\mathbf{x})\right) \longrightarrow \min_{\mathbf{u}_N} \quad \text{among } \mathbf{u}_N \colon Y^{\text{node}}_N \to \mathbb{R}^d -$$ - -where w is the local free energy density, bar{varepsilon} is the prescribed macroscopic strain, D is the discrete symmetrized gradient, u_N is the nodal displacement fluctuation - -**Euler-Lagrange equation (discrete equilibrium):** - -$$ -D^* \left[ \frac{\partial w}{\partial \boldsymbol{\varepsilon}}\!\left(\cdot,\, \bar{\boldsymbol{\varepsilon}} + D\mathbf{u}_N\right) \right] = \mathbf{0} -$$ - -where D* is the negative of the discrete divergence operator associated with the symmetrized gradient D - -**Semi-explicit Green's operator:** - -$$ -\hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) \text{ requires solving } \mathbf{A}(\boldsymbol{\xi})\,\hat{\mathbf{u}}(\boldsymbol{\xi}) = \hat{\mathbf{f}}(\boldsymbol{\xi}) -$$ - -where A(xi) is a Hermitian 3x3 acoustic tensor matrix at each frequency xi, computed from the FEM stencil Fourier transform; this inversion makes the operator semi-explicit rather than fully closed-form - -**Equivalence of Willot's scheme to reduced-integration FEM:** - -$$ -\left.\text{Willot's discretization}\right|_{\text{1 Gauss pt}} \equiv \left.\text{Trilinear hex FEM}\right|_{\text{reduced integration}} -$$ - -where Both evaluate at a single point per voxel (the voxel center), leading to identical discrete systems - -**Notation:** - -- $Y^{\text{node}}_N$ — Nodal grid — voxel corners where displacement degrees of freedom live -- $Y^{\text{Gauss}}_N$ — Gauss-point grid — 8 integration points per voxel element -- $D$ — Discrete symmetrized gradient operator (nodal grid to Gauss-point grid) -- $D^*$ — Negative discrete divergence operator (adjoint of D) -- $w$ — Local condensed free energy density -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain -- $\mathbf{u}_N$ — Nodal displacement fluctuation field - - -## 3. Algorithmic Implementation -**Algorithm: FANS (Fourier-Accelerated Nodal Solver)** - -$$ -\begin{algorithmic} -\State $\text{Input}\colon \bar{\boldsymbol{\varepsilon}},\; \mathbf{C}(\mathbf{x}),\; \text{tol}$ -\State $\mathbf{u}_N^{(0)} \leftarrow \mathbf{0} \text{ (initial guess on nodal grid)}$ -\While{$\|\mathbf{r}\| > \text{tol}$} - \State $\boldsymbol{\varepsilon}(\mathbf{x}) \leftarrow \bar{\boldsymbol{\varepsilon}} + D\mathbf{u}_N^{(k)}(\mathbf{x}) \quad \forall \mathbf{x} \in Y^{\text{Gauss}}_N \text{ (8 pts/voxel)}$ - \State $\boldsymbol{\sigma}(\mathbf{x}) \leftarrow \frac{\partial w}{\partial \boldsymbol{\varepsilon}}(\mathbf{x}, \boldsymbol{\varepsilon}(\mathbf{x})) \quad \text{(constitutive law at all Gauss pts)}$ - \State $\mathbf{r} \leftarrow D^* \boldsymbol{\sigma} \quad \text{(discrete residual on nodal grid)}$ - \State $\mathbf{K}_{\text{sparse}} \leftarrow \text{assemble sparse Newton tangent from } \partial\boldsymbol{\sigma}/\partial\boldsymbol{\varepsilon}$ - \State $\delta\mathbf{u} \leftarrow \text{CG solve with FFT-preconditioned } \mathbf{K}_{\text{sparse}}\,\delta\mathbf{u} = -\mathbf{r}$ - \State $\mathbf{u}_N^{(k+1)} \leftarrow \mathbf{u}_N^{(k)} + \delta\mathbf{u}$ -\EndWhile -\Return $\boldsymbol{\varepsilon},\; \boldsymbol{\sigma},\; \bar{\boldsymbol{\sigma}} = \langle \boldsymbol{\sigma} \rangle$ -\end{algorithmic} -$$ - - -## 4. Known Pitfalls -**Eightfold memory and computational overhead:** The full FEM-FFT approach with 8 Gauss points per voxel requires storing eight times the number of strain and stress fields compared to single-point schemes (Willot, Moulinec-Suquet). The constitutive law must also be evaluated eight times per voxel per iteration. This overhead can be prohibitive for large 3D microstructures. FANS mitigates this by operating on nodal displacements and storing the Newton tangent sparsely. - - -**Semi-explicit Green's operator cost:** Unlike finite difference discretizations that yield fully explicit (closed-form) Green's operators, the FEM discretization requires inverting a Hermitian $3 \times 3$ acoustic tensor matrix at every non-zero frequency point. While a $3 \times 3$ inversion is cheap per point, the cost accumulates over all $N_1 \times N_2 \times N_3$ frequency points and must be performed at each iteration (or precomputed and stored, adding memory overhead). - - -**Volumetric locking with full integration:** Fully integrated trilinear hexahedral elements are prone to volumetric locking when applied to nearly incompressible or highly plastic materials. The constraint ratio becomes too high, producing artificially stiff responses. FANS addresses this through selective reduced integration, where the volumetric part uses reduced integration while the deviatoric part uses full integration. - - -**Hourglass instabilities survive in under-integrated (Willot) variant:** The FEM interpretation reveals that Willot's scheme (equivalent to reduced-integration FEM) admits local hourglass modes for porous materials that cannot be fixed by the Nyquist-frequency zeroing strategy. Only the full 8-point integration or the standard staggered grid avoids these local instabilities. Users must understand that switching from Willot to full FEM is not just a refinement but a qualitative change in stability properties. - - -## 5. References -- Schneider, Merkert, Kabel (2017) — FFT-based solvers for trilinear hexahedral elements on regular periodic grids -- Fritzen and Leuschner (2013) — Fourier-Accelerated Nodal Solvers (FANS) with sparse Newton tangent and selective reduced integration -- Schneider (2021) — Review of nonlinear FFT-based computational homogenization, FEM-based discretizations - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-moulinec-suquet.md b/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-moulinec-suquet.md deleted file mode 100644 index 44cbddc..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-moulinec-suquet.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -id: fft-discretization-moulinec-suquet -title: Moulinec-Suquet Discretization (Original) -domain: fft-galerkin -subdomain: discretization -tags: -- fft-galerkin -- spectral -- discretization -- homogenization -- green-operator -- periodic-bc -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Discretizes the Lippmann-Schwinger equation via trigonometric collocation -- to: fft-green-operator - type: requires - weight: 1.0 - note: Uses the continuous Eshelby-Green operator evaluated at discrete frequencies -- to: fft-reference-medium - type: requires - weight: 0.9 - note: Requires a homogeneous reference medium C0 for the Lippmann-Schwinger formulation -- to: fft-freq-grid - type: requires - weight: 0.9 - note: Operates on the discrete frequency grid Z_N with Nyquist treatment -- to: fft-solver-basic-scheme - type: feeds-into - weight: 1.0 - note: The basic scheme fixed-point iteration is the canonical solver for this discretization -- to: fft-galerkin-basics - type: feeds-into - weight: 0.7 - note: Galerkin discretization refines Moulinec-Suquet by replacing collocation with projection -- to: fft-discretization-willot - type: feeds-into - weight: 0.6 - note: Willot's scheme was developed as a finite-difference alternative to this spectral approach -- to: fft-composite-voxels - type: feeds-into - weight: 0.7 - note: Composite voxels improve interface resolution of the standard voxelized discretization -context_size: large -reading_priority: full -load_with: -- fft-lippmann-schwinger -- fft-green-operator -- fft-solver-basic-scheme -content_ref: null -akms_schema: v2 ---- - -# Moulinec-Suquet Discretization (Original) - -## Summary -The Moulinec-Suquet discretization (1994) is the original FFT-based computational homogenization scheme for periodic microstructures. It discretizes the Lippmann-Schwinger integral equation on a regular voxel grid by introducing a homogeneous reference medium and solving via fixed-point (Picard) iteration. The method can be interpreted either as trigonometric collocation (the DFT interpolates discrete field values as global trigonometric polynomials via operator $Q_N$) or equivalently as a non-conforming Galerkin approximation where spatial integrals are evaluated with the trapezoidal quadrature rule. The continuous Eshelby-Green operator is used directly at the discrete frequencies, and the constitutive law is evaluated locally at voxel centers. The scheme suffers from Gibbs ringing at sharp interfaces, convergence degradation with increasing phase contrast, and outright failure for porous materials with infinite contrast. - - -## 1. Core Concept -The Moulinec-Suquet method transforms the governing PDEs of a heterogeneous elastic medium into a periodic Lippmann-Schwinger integral equation by introducing a homogeneous reference medium $\mathbf{C}^0$. The local strain fluctuations caused by material heterogeneities are treated as an eigenstrain (stress polarization) field $\boldsymbol{\tau} = \boldsymbol{\sigma}(\boldsymbol{\varepsilon}) - \mathbf{C}^0 : \boldsymbol{\varepsilon}$ within this reference medium. The continuous fields are discretized on a regular voxel grid, and the DFT finds the unique trigonometric polynomial that interpolates discrete values at voxel centers. This is a trigonometric collocation approach: the continuous balance of linear momentum is solved exactly, but the constitutive law is approximated via trigonometric interpolation at the grid points. Equivalently, the scheme can be derived from the continuous variational principle of minimum potential energy with the trapezoidal quadrature rule replacing exact spatial integration. A crucial feature is that the method uses the exact continuous Green's operator $\hat{\boldsymbol{\Gamma}}^0$ evaluated at discrete frequencies, not a modified discrete operator. - - -## 2. Mathematical Formulation -The Moulinec-Suquet discretization operates on a regular grid $Y_N$ with corresponding frequency set $Z_N$. The strain field is decomposed as $\boldsymbol{\varepsilon}(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}} + \tilde{\boldsymbol{\varepsilon}}(\mathbf{x})$ with $\bar{\boldsymbol{\varepsilon}}$ the prescribed macroscopic strain. The stress polarization captures the deviation from the reference medium response. The continuous Green's operator maps this polarization to strain fluctuations in Fourier space, vanishing at zero frequency (macroscopic strain is prescribed) and requiring special treatment at Nyquist frequencies on even grids. The trigonometric collocation operator $Q_N$ interpolates grid-point values as global trigonometric polynomials. - - -**Discretized Lippmann-Schwinger equation (collocation form):** - -$$ -\boldsymbol{\varepsilon}_{k+1} = \bar{\boldsymbol{\varepsilon}} - \boldsymbol{\Gamma}^0 : Q_N \left[ \frac{\partial w}{\partial \boldsymbol{\varepsilon}}(\cdot, \boldsymbol{\varepsilon}_k) - \mathbf{C}^0 : \boldsymbol{\varepsilon}_k \right] -$$ - -where Gamma0 is the continuous Green's operator, Q_N is the trigonometric interpolation operator, w is the free energy density, C0 is the reference medium stiffness, eps_bar is macroscopic strain - -**Stress polarization (linear elasticity):** - -$$ -\boldsymbol{\tau}^k(\mathbf{x}_I) = [\mathbf{C}(\mathbf{x}_I) - \mathbf{C}^0] : \boldsymbol{\varepsilon}^k(\mathbf{x}_I), \quad \mathbf{x}_I \in Y_N -$$ - -where C(x_I) is local stiffness at grid point x_I, C0 is reference medium, eps^k is strain at iteration k - -**Fourier-space strain update (non-zero frequencies):** - -$$ -\hat{\boldsymbol{\varepsilon}}^{k+1}(\boldsymbol{\xi}) = -\hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) : \hat{\boldsymbol{\tau}}^k(\boldsymbol{\xi}), \quad \boldsymbol{\xi} \in Z_N \setminus \{\mathbf{0}\} -$$ - -where hat denotes Fourier transform; at xi=0 the macroscopic strain is enforced: hat{eps}(0) = eps_bar - -**Continuous Green's operator for isotropic reference (C0 = 2 mu0 Id):** - -$$ -(\hat{\boldsymbol{\Gamma}}^0 : \hat{\boldsymbol{\tau}})(\boldsymbol{\xi}) = \frac{1}{\mu_0} \left[ \frac{\boldsymbol{\xi}_Y \otimes^s (\hat{\boldsymbol{\tau}} \boldsymbol{\xi}_Y)}{\|\boldsymbol{\xi}_Y\|^2} - \frac{\boldsymbol{\xi}_Y \cdot (\hat{\boldsymbol{\tau}} \boldsymbol{\xi}_Y)}{2\|\boldsymbol{\xi}_Y\|^4} \boldsymbol{\xi}_Y \otimes \boldsymbol{\xi}_Y \right] -$$ - -where xi_Y = (2 pi xi_1/L_1, ..., 2 pi xi_d/L_d) is the re-scaled frequency vector, mu_0 is reference shear modulus - -**Trapezoidal quadrature variational form:** - -$$ -\sum_{\mathbf{x}_I \in Y_N} w(\mathbf{x}_I, \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_N(\mathbf{x}_I)) \longrightarrow \min_{\mathbf{u}_N \in T_N} -$$ - -where w is local free energy, u_N is displacement fluctuation in trigonometric polynomial space T_N - -**Convergence criterion (equilibrium residual in Fourier space):** - -$$ -\frac{\sqrt{\sum_{\boldsymbol{\xi}} \| \boldsymbol{\xi} \cdot \hat{\boldsymbol{\sigma}}^k(\boldsymbol{\xi}) \|^2}}{\| \hat{\boldsymbol{\sigma}}^k(\mathbf{0}) \|} < \text{tol} -$$ - -where hat{sigma}^k(0) is the macroscopic (mean) stress, the numerator measures the L2 norm of stress divergence via Parseval's theorem - -**Notation:** - -- $\boldsymbol{\Gamma}^0$ — Continuous Eshelby-Green operator of the reference medium -- $\hat{\boldsymbol{\Gamma}}^0$ — Fourier-space form of the Green's operator -- $Q_N$ — Trigonometric interpolation (collocation) operator mapping grid values to global trigonometric polynomials -- $\mathbf{C}^0$ — Stiffness of the homogeneous reference medium -- $\mathbf{C}(\mathbf{x})$ — Local heterogeneous stiffness tensor -- $\boldsymbol{\tau}$ — Stress polarization field (difference between true stress and reference stress) -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain -- $\tilde{\boldsymbol{\varepsilon}}$ — Periodic strain fluctuation -- $\boldsymbol{\xi}_Y$ — Re-scaled frequency vector: (2 pi xi_j / L_j) -- $\mu_0$ — Shear modulus of the isotropic reference medium -- $\otimes^s$ — Symmetrized tensor product -- $w$ — Local condensed free energy density -- $T_N$ — Space of trigonometric polynomials of order N -- $Y_N$ — Discrete regular spatial grid of voxel centers -- $Z_N$ — Discrete frequency set: {xi in Z^d | -N_j/2 <= xi_j < N_j/2} - - -## 3. Algorithmic Implementation -**Algorithm: Algorithm** - -$$ -\begin{algorithmic} -\State $\boldsymbol{\varepsilon}^0(\mathbf{x}) \gets \bar{\boldsymbol{\varepsilon}} \quad \text{(initialize strain to macroscopic strain at all grid points)}$ -\For{$$} -\State $\boldsymbol{\tau}^k(\mathbf{x}_I) \gets [\mathbf{C}(\mathbf{x}_I) - \mathbf{C}^0] \colon \boldsymbol{\varepsilon}^k(\mathbf{x}_I) \quad \text{for all } \mathbf{x}_I \in Y_N$ -\State $\hat{\boldsymbol{\tau}}^k(\boldsymbol{\xi}) \gets \mathcal{F}\{\boldsymbol{\tau}^k(\mathbf{x})\}$ -\State $\hat{\tilde{\boldsymbol{\varepsilon}}}^{k+1}(\boldsymbol{\xi}) \gets -\hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) \colon \hat{\boldsymbol{\tau}}^k(\boldsymbol{\xi}) \quad \text{for } \boldsymbol{\xi} \in Z_N \setminus \{\mathbf{0}\}$ -\State $\hat{\boldsymbol{\varepsilon}}^{k+1}(\mathbf{0}) \gets \bar{\boldsymbol{\varepsilon}}$ -\State $\hat{\boldsymbol{\varepsilon}}^{k+1}(\boldsymbol{\xi}_{\text{Nyq}}) \gets \mathbf{0} \quad \text{(force Nyquist frequencies to zero)}$ -\State $\boldsymbol{\varepsilon}^{k+1}(\mathbf{x}) \gets \mathcal{F}^{-1}\{\hat{\boldsymbol{\varepsilon}}^{k+1}(\boldsymbol{\xi})\}$ -\State $\boldsymbol{\sigma}^{k+1}(\mathbf{x}_I) \gets \mathbf{C}(\mathbf{x}_I) \colon \boldsymbol{\varepsilon}^{k+1}(\mathbf{x}_I)$ -\State $e_{k+1} \gets \frac{\sqrt{\sum_{\boldsymbol{\xi}} \| \boldsymbol{\xi} \cdot \hat{\boldsymbol{\sigma}}^{k+1}(\boldsymbol{\xi}) \|^2}}{\| \hat{\boldsymbol{\sigma}}^{k+1}(\mathbf{0}) \|}$ -\If{$$} -\State $\textbf{break}$ -\EndIf -\EndFor -\Return $\boldsymbol{\varepsilon}^{k+1}(\mathbf{x}), \boldsymbol{\sigma}^{k+1}(\mathbf{x})$ -\end{algorithmic} -$$ - - -## 4. Known Pitfalls -**Gibbs ringing at material interfaces:** The scheme uses global trigonometric polynomials to interpolate fields, which causes pronounced high-frequency ringing artifacts (Gibbs phenomenon) near sharp material interfaces and non-smooth boundaries. While macroscopic effective properties remain accurate, the local microscopic fields exhibit reduced accuracy compared to finite-difference or finite-element discretizations. - - -**Sensitivity to reference medium choice:** The reference medium $\mathbf{C}^0$ is a purely numerical parameter that does not affect the converged solution, but it critically controls the stability and convergence rate of the fixed-point iteration. Poor choice leads to slow convergence or instability. For linear elasticity, the optimal choice is the arithmetic mean of the phase stiffnesses. - - -**Convergence degradation with stiffness contrast:** The convergence rate of the basic scheme deteriorates severely as the stiffness contrast between phases increases. The number of iterations required scales proportionally to the phase contrast ratio, making the scheme impractical for composites with very stiff inclusions in a compliant matrix (or vice versa) without accelerated solvers. - - -**Failure for porous/void materials (infinite contrast):** Convergence is not ensured for materials with infinite phase contrast, such as porous foams. The scheme requires a continuous elastic extension into pore space, but trigonometric polynomials are global functions that cannot accommodate the required boundary values at solid-pore interfaces. Any small numerical error at the void boundary propagates globally, preventing convergence and yielding unphysical results (e.g., average stress converging to zero). - - -**Trigonometric interpolation accuracy at discontinuities:** The constitutive law is evaluated exactly only at voxel centers; the resulting stress field is interpolated globally via trigonometric polynomials. At material discontinuities, this global interpolation introduces errors because it fits continuous polynomials to physically discontinuous fields. The accuracy of local fields is inherently limited by these interpolation errors. - - -**Nyquist frequency symmetry loss on even grids:** On grids with even number of voxels, frequency symmetry is lost at the Nyquist frequencies. The Fourier coefficients of the strain must be forced to zero at these frequencies (or the Green's operator modified) to ensure the resulting real-space fields remain purely real-valued. Failure to handle this produces complex-valued (non-physical) mechanical fields. - - -## 5. References -- Moulinec, Suquet (1994) — Original FFT-based homogenization method -- Moulinec, Suquet (1998) — Accelerated scheme and convergence analysis -- Schneider (2021) — Moulinec-Suquet discretization as trigonometric collocation and trapezoidal quadrature - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-staggered.md b/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-staggered.md deleted file mode 100644 index c0492e9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-staggered.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -id: fft-discretization-staggered -title: Staggered Grid Discretization -domain: fft-galerkin -subdomain: discretization-schemes -tags: -- discretization -- staggered-grid -- finite-difference -- fft-galerkin -- spectral -- homogenization -- periodic-bc -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-discretization-willot - type: refines - weight: 1.0 - note: Staggered grid uses standard (non-rotated) staggering as alternative to Willot's rotated scheme -- to: fft-green-operator - type: requires - weight: 0.9 - note: Staggered grid modifies the Green's operator via complex-valued frequency vectors -- to: fft-freq-grid - type: requires - weight: 0.8 - note: Modified frequency vector depends on discrete frequency grid construction -- to: fft-lippmann-schwinger - type: feeds-into - weight: 0.9 - note: Lippmann-Schwinger solvers can be constructed for the staggered grid discretization -- to: fft-discretization-moulinec-suquet - type: refines - weight: 0.7 - note: Staggered grid replaces the continuous derivative with forward/backward finite difference stencils -context_size: large -reading_priority: full -load_with: -- fft-discretization-willot -- fft-green-operator -- fft-freq-grid -content_ref: null -akms_schema: v2 ---- - -# Staggered Grid Discretization - -## Summary -The staggered grid discretization for FFT-based homogenization adapts concepts from finite volume methods in fluid dynamics. Displacements live on voxel faces while strains, stresses, and material properties are evaluated at voxel centers. This physical separation of field evaluation points naturally mitigates hourglass instabilities that plague Willot's rotated staggered grid in porous materials. The scheme uses forward and backward finite difference operators to define a discrete symmetrized gradient, and yields an explicit Green's operator in Fourier space via a modified complex-valued frequency vector. - - -## 1. Core Concept -In the staggered grid approach, each voxel is treated as a control volume. Displacements live on voxel faces (analogous to velocities in fluid dynamics), while strains and stresses are evaluated strictly at voxel centers. This arrangement uses specific combinations of forward ($D^+$) and backward ($D^-$) finite difference operators to construct a discrete symmetrized gradient operator. Unlike Willot's rotated staggered grid (which evaluates at a single voxel-center Gauss point and is equivalent to reduced-integration FEM), the standard staggered grid physically separates the evaluation points across faces and centers. This separation is key to its robustness for porous materials, where Willot's scheme suffers from local hourglass instabilities that cannot be stabilized by zeroing the Green's operator at Nyquist frequencies. The staggered grid is compatible with fully anisotropic material behavior. - - -## 2. Mathematical Formulation -The staggered grid defines a discrete symmetrized gradient operator $D$ using forward ($D^+_j$) and backward ($D^-_j$) finite difference operators in each coordinate direction $j$. In Fourier space, these stencils produce a modified complex-valued frequency vector $k_j$ that replaces the continuous spatial derivative. The Green's operator action is then computed via a sequence of algebraic steps involving the normalized frequency vector and its complex conjugate. - - -**Discrete symmetrized gradient operator (3D):** - -$$ -D\mathbf{u} = \begin{bmatrix} D^+_1 u_1 & \frac{1}{2}(D^-_1 u_2 + D^-_2 u_1) & \frac{1}{2}(D^-_1 u_3 + D^-_3 u_1) \\ \frac{1}{2}(D^-_2 u_1 + D^-_1 u_2) & D^+_2 u_2 & \frac{1}{2}(D^-_2 u_3 + D^-_3 u_2) \\ \frac{1}{2}(D^-_3 u_1 + D^-_1 u_3) & \frac{1}{2}(D^-_3 u_2 + D^-_2 u_3) & D^+_3 u_3 \end{bmatrix} -$$ - -where D+_j and D-_j are forward and backward finite difference operators in direction j, u_i are displacement components on voxel faces - -**Modified frequency vector (staggered grid):** - -$$ -k_j = \left(e^{-2\pi i \xi_j / N_j} - 1\right) \frac{N_j}{L_j} -$$ - -where xi_j is the integer frequency index, N_j the number of voxels, L_j the cell dimension in direction j - -**Normalized frequency vector:** - -$$ -\boldsymbol{\eta} = \mathbf{k} / \|\mathbf{k}\| -$$ - -where k is the modified complex-valued frequency vector, bar{eta} denotes its complex conjugate - -**Auxiliary force vector (staggered grid):** - -$$ -\mathbf{f} = \begin{bmatrix} -\hat{\tau}_{11}(\boldsymbol{\xi})\eta_1 + \hat{\tau}_{12}(\boldsymbol{\xi})\bar{\eta}_2 + \hat{\tau}_{13}(\boldsymbol{\xi})\bar{\eta}_3 \\ \hat{\tau}_{21}(\boldsymbol{\xi})\bar{\eta}_1 - \hat{\tau}_{22}(\boldsymbol{\xi})\eta_2 + \hat{\tau}_{23}(\boldsymbol{\xi})\bar{\eta}_3 \\ \hat{\tau}_{31}(\boldsymbol{\xi})\bar{\eta}_1 + \hat{\tau}_{32}(\boldsymbol{\xi})\bar{\eta}_2 - \hat{\tau}_{33}(\boldsymbol{\xi})\eta_3 \end{bmatrix} -$$ - -where hat{tau}_{ij} are Fourier-space stress polarization components, eta_j and bar{eta}_j are the normalized frequency and its conjugate - -**Scalar projection and displacement intermediate:** - -$$ -s = \mathbf{f} \cdot \bar{\boldsymbol{\eta}}, \quad \mathbf{u} = \frac{-\mathbf{f} + s\,\boldsymbol{\eta}/2}{\mu_0} -$$ - -where mu_0 is the reference shear modulus - -**Strain fluctuation assembly (staggered grid):** - -$$ -\hat{\boldsymbol{\varepsilon}}(\boldsymbol{\xi}) = \begin{bmatrix} -\bar{\eta}_1 u_1 & \frac{\eta_1 u_2 + \eta_2 u_1}{2} & \frac{\eta_1 u_3 + \eta_3 u_1}{2} \\ \frac{\eta_2 u_1 + \eta_1 u_2}{2} & -\bar{\eta}_2 u_2 & \frac{\eta_2 u_3 + \eta_3 u_2}{2} \\ \frac{\eta_3 u_1 + \eta_1 u_3}{2} & \frac{\eta_3 u_2 + \eta_2 u_3}{2} & -\bar{\eta}_3 u_3 \end{bmatrix} -$$ - -where u_i are the displacement intermediate vector components - -**Notation:** - -- $D^+_j, D^-_j$ — Forward and backward finite difference operators in direction j -- $k_j$ — Modified complex-valued frequency component for the staggered grid -- $\boldsymbol{\eta}$ — Normalized modified frequency vector -- $\bar{\boldsymbol{\eta}}$ — Complex conjugate of the normalized frequency vector -- $\mu_0$ — Shear modulus of the isotropic reference medium -- $\hat{\boldsymbol{\tau}}$ — Stress polarization field in Fourier space - - -## 3. Algorithmic Implementation -**Algorithm: Staggered Grid Green's Operator Application** - -$$ -\begin{algorithmic} -\For{$j = 1, 2, 3$} - \State $k_j \leftarrow (e^{-2\pi i \xi_j / N_j} - 1) N_j / L_j$ -\EndFor -\State $\boldsymbol{\eta} \leftarrow \mathbf{k} / \|\mathbf{k}\|$ -\State $f_1 \leftarrow -\hat{\tau}_{11}\eta_1 + \hat{\tau}_{12}\bar{\eta}_2 + \hat{\tau}_{13}\bar{\eta}_3$ -\State $f_2 \leftarrow \hat{\tau}_{21}\bar{\eta}_1 - \hat{\tau}_{22}\eta_2 + \hat{\tau}_{23}\bar{\eta}_3$ -\State $f_3 \leftarrow \hat{\tau}_{31}\bar{\eta}_1 + \hat{\tau}_{32}\bar{\eta}_2 - \hat{\tau}_{33}\eta_3$ -\State $s \leftarrow \mathbf{f} \cdot \bar{\boldsymbol{\eta}}$ -\State $\mathbf{u} \leftarrow (-\mathbf{f} + s\,\boldsymbol{\eta}/2) / \mu_0$ -\State $\hat{\varepsilon}_{ij} \leftarrow \text{assemble from } \boldsymbol{\eta}, \bar{\boldsymbol{\eta}}, \mathbf{u} \text{ (see strain fluctuation formula)}$ -\Return $\hat{\boldsymbol{\varepsilon}}(\boldsymbol{\xi})$ -\end{algorithmic} -$$ - - -## 4. Known Pitfalls -**Non-symmetric solutions for symmetric geometries:** Because the grid staggering breaks perfect spatial symmetry by placing displacement components on varying voxel faces while evaluating strains at centers, the computed solution fields for a symmetric geometry may turn out non-symmetric. This is generally not problematic for naturally complex, non-symmetric microstructures but can be confusing during verification on simple test cases. - - -**Implementation complexity versus Willot scheme:** The staggered grid operator requires careful handling of forward and backward difference operators, complex-valued frequency vectors, and their conjugates in a multi-step algebraic sequence. This is significantly more complex than Willot's scheme or the continuous Moulinec-Suquet formulation, and sign/conjugation errors in the auxiliary vector $\mathbf{f}$ assembly are common implementation bugs. - - -**Interface artifacts at sharp material boundaries:** Like all regular-grid discretizations, the staggered grid produces numerical artifacts at sharp material interfaces. While it avoids the severe checkerboarding of Willot's scheme and the global ringing of the Moulinec-Suquet discretization, minor localized inaccuracies at the interface remain present. - - -**Anisotropy limitations noted in summary tables:** Although the staggered grid is compatible with anisotropic materials (unlike the finite volume discretization which is restricted to isotropic conductivity), it is listed with a caveat "(+)" for anisotropic support in Schneider's summary, indicating that practical implementation for fully general anisotropy requires additional care. - - -## 5. References -- Schneider, Ospald, Kabel (2016) — Computational homogenization of elasticity on a staggered grid -- Schneider (2021) — Review of nonlinear FFT-based computational homogenization methods, staggered grid discretization -- Harlow and Welch (1965) — Original staggered grid concept for fluid dynamics - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-willot.md b/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-willot.md deleted file mode 100644 index 422ebd8..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-discretization-willot.md +++ /dev/null @@ -1,203 +0,0 @@ ---- -id: fft-discretization-willot -title: Willot's Rotated Finite Difference Scheme -domain: fft-galerkin -subdomain: discretization -tags: -- discretization -- finite-difference -- staggered-grid -- fft-galerkin -- homogenization -- periodic-bc -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-discretization-moulinec-suquet - type: refines - weight: 0.9 - note: Developed as a finite-difference alternative to eliminate Gibbs ringing of the Moulinec-Suquet spectral approach -- to: fft-green-operator - type: requires - weight: 0.9 - note: Uses a discrete Green's operator with modified frequency vector k(xi) replacing the continuous xi_Y -- to: fft-freq-grid - type: requires - weight: 0.8 - note: Operates on the same discrete frequency grid Z_N but with modified frequency vectors -- to: fft-lippmann-schwinger - type: requires - weight: 0.8 - note: Integrates with the Lippmann-Schwinger iteration via the discrete Green's operator -- to: fft-galerkin-basics - type: feeds-into - weight: 0.5 - note: Alternative discretization approach; shares variational foundation but uses local FD stencils -- to: fft-solver-basic-scheme - type: feeds-into - weight: 0.8 - note: Compatible with both strain-based and displacement-based solver formulations -- to: fft-discretization-staggered - type: refines - weight: 0.7 - note: Willot's rotated grid is a specific variant of the staggered grid family -context_size: large -reading_priority: full -load_with: -- fft-discretization-moulinec-suquet -- fft-green-operator -content_ref: null -akms_schema: v2 ---- - -# Willot's Rotated Finite Difference Scheme - -## Summary -Willot's rotated finite difference scheme replaces the exact continuous spatial derivatives of the Fourier-Galerkin and Moulinec-Suquet methods with central finite difference approximations on a rotated staggered grid, eliminating Gibbs ringing artifacts at material interfaces. Displacements live at voxel corners (nodal grid) while strains and stresses are evaluated at voxel centers (Gauss-point grid). The scheme is mathematically identical to trilinear hexahedral finite elements with reduced integration (one Gauss point per voxel). In Fourier space, the finite difference stencil yields a modified complex-valued frequency vector $k(\boldsymbol{\xi})$ that replaces the continuous $\boldsymbol{\xi}_Y$ in all operator definitions. The scheme enables displacement-based solver formulations that halve the memory footprint for 3D elasticity. Key limitations include checkerboarding artifacts inside inclusions, susceptibility to global hourglass instabilities requiring Nyquist zeroing, and convergence difficulties in highly porous microstructures. - - -## 1. Core Concept -Willot's rotated finite difference scheme operates on a rotated staggered grid where nodal displacements $\mathbf{u}_N$ are placed at voxel corners and gradients (strains) and stresses are evaluated at voxel centers. The grid architecture is conceptually a "resistor network" connecting diametrically opposite corners of each voxel, with connections meeting exactly at the center. Through a coordinate transformation, the gradient at the voxel center equals the averaged forward differences along coordinate axes. In Fourier space, this finite difference stencil produces a modified complex-valued frequency vector $k(\boldsymbol{\xi})$ that replaces the continuous re-scaled frequency vector $\boldsymbol{\xi}_Y$ in the Green's operator and all spatial derivative operators. The resulting system is mathematically identical to trilinear hexahedral finite elements (Q1 elements) with reduced integration at a single Gauss point per element located at the voxel center. Because the discrete gradient $D$ and divergence $D^*$ operators are defined between distinct sub-grids, iterative solvers can be formulated directly for the displacement field rather than the strain field, reducing memory by a factor of two for 3D elasticity. - - -## 2. Mathematical Formulation -The key mathematical object is the modified frequency vector $k(\boldsymbol{\xi})$, which encodes the rotated finite difference stencil in Fourier space. All spatial operators (gradient, divergence, Green's operator) are expressed algebraically in terms of $k(\boldsymbol{\xi})$ and its complex conjugate $\overline{k(\boldsymbol{\xi})}$. The discrete gradient maps nodal displacements to voxel-center strains via symmetrized tensor product with $k$, while the discrete divergence maps voxel-center stresses to nodal forces via contraction with $\overline{k}$. The discrete Green's operator retains the same algebraic structure as the continuous one but with $k(\boldsymbol{\xi})$ replacing $\boldsymbol{\xi}_Y$. Frequencies where $k(\boldsymbol{\xi}) = 0$ (including Nyquist) form the undefined set $U_N$ where the operator is forced to zero. - - -**Modified frequency vector (3D, rotated staggered grid):** - -$$ -k(\boldsymbol{\xi}) = \begin{bmatrix} -\frac{N_1}{4L_1} (e^{2\pi i \xi_1/N_1} - 1)(e^{2\pi i \xi_2/N_2} + 1)(e^{2\pi i \xi_3/N_3} + 1) \\ -\frac{N_2}{4L_2} (e^{2\pi i \xi_1/N_1} + 1)(e^{2\pi i \xi_2/N_2} - 1)(e^{2\pi i \xi_3/N_3} + 1) \\ -\frac{N_3}{4L_3} (e^{2\pi i \xi_1/N_1} + 1)(e^{2\pi i \xi_2/N_2} + 1)(e^{2\pi i \xi_3/N_3} - 1) -\end{bmatrix} -$$ - -where N_j is number of voxels in dimension j, L_j is cell length in dimension j, xi_j are integer frequency indices - -**Discrete symmetrized gradient operator:** - -$$ -(\widehat{D\mathbf{u}})(\boldsymbol{\xi}) = k(\boldsymbol{\xi}) \otimes^s \hat{\mathbf{u}}(\boldsymbol{\xi}) -$$ - -where D maps nodal displacements to voxel-center strains, otimes^s is symmetrized tensor product - -**Discrete divergence operator:** - -$$ -(\widehat{D^*\boldsymbol{\tau}})(\boldsymbol{\xi}) = \hat{\boldsymbol{\tau}}(\boldsymbol{\xi}) \, \overline{k(\boldsymbol{\xi})} -$$ - -where D* maps voxel-center stresses to nodal forces, overline denotes complex conjugate - -**Discrete Green's operator (isotropic reference C0 = 2 mu0 Id):** - -$$ -(\hat{\boldsymbol{\Gamma}}^0_N \hat{\boldsymbol{\tau}})(\boldsymbol{\xi}) = \frac{1}{\mu_0} \left[ \frac{k(\boldsymbol{\xi}) \otimes^s (\hat{\boldsymbol{\tau}} \, \overline{k(\boldsymbol{\xi})})}{\|k(\boldsymbol{\xi})\|^2} - \frac{1}{2} \frac{k(\boldsymbol{\xi}) \cdot (\hat{\boldsymbol{\tau}} \, \overline{k(\boldsymbol{\xi})})}{\|k(\boldsymbol{\xi})\|^4} k(\boldsymbol{\xi}) \otimes \overline{k(\boldsymbol{\xi})} \right] -$$ - -where Valid for xi not in U_N; mu_0 is reference shear modulus; the algebraic structure matches the continuous operator with k replacing xi_Y - -**Discrete Green's operator (structural form):** - -$$ -\hat{\boldsymbol{\Gamma}}^0_N = D(D^* \mathbf{C}^0 D)^{-1} D^* -$$ - -where Compositional form showing relationship between gradient, divergence, and reference stiffness operators - -**Undefined frequency set:** - -$$ -U_N = \{\boldsymbol{\xi} = \mathbf{0}\} \cup \{\boldsymbol{\xi} \mid 2\xi_j = -N_j \text{ for some } j\} -$$ - -where Includes zero frequency and all Nyquist frequencies; Green's operator is forced to zero on U_N - -**Displacement-based Green's operator:** - -$$ -\mathbf{G}^0_N = (D^* \mathbf{C}^0 D)^{-1} -$$ - -where Maps nodal forces to displacement corrections; enables displacement-based solver with half the memory - -**Displacement-based basic scheme update:** - -$$ -\mathbf{u}^{k+1}_N = - \mathbf{G}^0_N D^* \left[ \frac{\partial w}{\partial \boldsymbol{\varepsilon}}(\cdot, \bar{\boldsymbol{\varepsilon}} + D \mathbf{u}^k_N) - \mathbf{C}^0 : D \mathbf{u}^k_N \right] -$$ - -where u_N is nodal displacement, D u_N gives voxel-center strain, w is free energy, C0 is reference stiffness - -**Notation:** - -- $k(\boldsymbol{\xi})$ — Modified complex-valued frequency vector from the rotated FD stencil -- $\overline{k(\boldsymbol{\xi})}$ — Complex conjugate of the modified frequency vector -- $D$ — Discrete symmetrized gradient operator (nodal grid to Gauss-point grid) -- $D^*$ — Discrete divergence operator (Gauss-point grid to nodal grid), adjoint of D -- $\hat{\boldsymbol{\Gamma}}^0_N$ — Discrete Green's operator using modified frequency vector -- $\mathbf{G}^0_N$ — Displacement-based discrete Green's operator -- $U_N$ — Set of undefined frequencies (zero + Nyquist) where operator is zeroed -- $Y^{node}_N$ — Nodal grid at voxel corners where displacements live -- $Y^{Gauss}_N$ — Gauss-point grid at voxel centers where strains/stresses are evaluated -- $\otimes^s$ — Symmetrized tensor product -- $\mu_0$ — Shear modulus of the isotropic reference medium -- $\mathbf{C}^0$ — Reference medium stiffness tensor -- $w$ — Local condensed free energy density - - -## 3. Algorithmic Implementation -**Algorithm: Algorithm** - -$$ -\begin{algorithmic} -\State $\text{Set up frequency grid } Z_N \text{ and compute } k(\boldsymbol{\xi}) \text{ for all } \boldsymbol{\xi} \in Z_N$ -\State $k_j(\boldsymbol{\xi}) \gets \frac{N_j}{4L_j} (e^{2\pi i \xi_j/N_j} - 1) \prod_{m \neq j} (e^{2\pi i \xi_m/N_m} + 1)$ -\State $U_N \gets \{\boldsymbol{\xi} = \mathbf{0}\} \cup \{\boldsymbol{\xi} \mid 2\xi_j = -N_j \text{ for some } j\}$ -\State $\boldsymbol{\varepsilon}^0_N(\mathbf{x}) \gets \bar{\boldsymbol{\varepsilon}} \quad \text{(initialize strain at voxel centers)}$ -\For{$$} -\State $\boldsymbol{\tau}^k(\mathbf{x}) \gets [\mathbf{C}(\mathbf{x}) - \mathbf{C}^0] \colon \boldsymbol{\varepsilon}^k_N(\mathbf{x}) \quad \text{(polarization at voxel centers)}$ -\State $\hat{\boldsymbol{\tau}}^k(\boldsymbol{\xi}) \gets \mathcal{F}\{\boldsymbol{\tau}^k(\mathbf{x})\}$ -\If{$$} -\State $\hat{\boldsymbol{\varepsilon}}^{k+1}_N(\boldsymbol{\xi}) \gets \hat{\bar{\boldsymbol{\varepsilon}}} - \frac{1}{\mu_0} \left[ \frac{k \otimes^s (\hat{\boldsymbol{\tau}}^k \overline{k})}{\|k\|^2} - \frac{1}{2} \frac{k \cdot (\hat{\boldsymbol{\tau}}^k \overline{k})}{\|k\|^4} k \otimes \overline{k} \right]$ -\Else -\State $\hat{\boldsymbol{\varepsilon}}^{k+1}_N(\boldsymbol{\xi}) \gets \hat{\bar{\boldsymbol{\varepsilon}}} \delta_{\boldsymbol{\xi},\mathbf{0}} \quad \text{(zero for Nyquist, macroscopic strain for } \boldsymbol{\xi}=\mathbf{0}\text{)}$ -\EndIf -\State $\boldsymbol{\varepsilon}^{k+1}_N(\mathbf{x}) \gets \mathcal{F}^{-1}\{\hat{\boldsymbol{\varepsilon}}^{k+1}_N(\boldsymbol{\xi})\}$ -\State $\boldsymbol{\sigma}^{k+1}(\mathbf{x}) \gets \mathbf{C}(\mathbf{x}) \colon \boldsymbol{\varepsilon}^{k+1}_N(\mathbf{x})$ -\State $e_{k+1} \gets \frac{\sqrt{\sum_{\boldsymbol{\xi}} \| k(\boldsymbol{\xi}) \cdot \hat{\boldsymbol{\sigma}}^{k+1}(\boldsymbol{\xi}) \|^2}}{\| \hat{\boldsymbol{\sigma}}^{k+1}(\mathbf{0}) \|}$ -\If{$$} -\State $\textbf{break}$ -\EndIf -\EndFor -\Return $\boldsymbol{\varepsilon}^{k+1}_N(\mathbf{x}), \boldsymbol{\sigma}^{k+1}(\mathbf{x})$ -\end{algorithmic} -$$ - - -## 4. Known Pitfalls -**Checkerboarding artifacts inside inclusions:** Willot's discrete stencil introduces pronounced checkerboarding artifacts in the local microscopic fields, particularly visible inside inclusion phases. These replace the Gibbs ringing of the continuous operator but can still reduce the accuracy of local field predictions. - - -**Global hourglass instabilities:** Because the scheme is equivalent to trilinear FEM with reduced integration (one Gauss point per voxel), it is inherently susceptible to global hourglass instabilities — zero-energy deformation modes that are invisible to the single-point evaluation. The discrete Green's operator must be artificially set to zero at all Nyquist frequencies to suppress these modes. Failure to do so leads to divergent, non-physical solutions. - - -**Convergence failure in highly porous microstructures:** Although the local finite difference approach handles solid-pore interfaces better than global spectral methods, highly porous microstructures (e.g., ~40% porosity bound sand) can trigger local hourglass instabilities not stabilized by Nyquist zeroing. Iterative solvers typically stall after initial error reduction and fail to converge to tight tolerances, making the scheme less robust than the standard staggered grid for such applications. - - -**Staggered grid interpolation requirement:** Displacements live on the nodal grid (voxel corners) while strains, stresses, and material properties are evaluated at voxel centers (Gauss-point grid). If continuous field compatibility is required at identical spatial coordinates, additional interpolation between the two sub-grids is needed, adding complexity. - - -**No guaranteed variational bounds:** Unlike the Fourier-Galerkin discretization, which generates rigorous upper and lower bounds on effective elastic properties via exact integration over trigonometric polynomials, Willot's finite difference approximation cannot provide guaranteed theoretical bounds on homogenized properties. The effective properties are approximations without certified error bounds. - - -## 5. References -- Willot (2015) — Rotated finite difference scheme for FFT-based homogenization -- Schneider (2021) — Comparison of discretization schemes including Willot's rotated staggered grid -- Schneider, Ospald, Kabel (2017) — Equivalence of Willot scheme to trilinear FEM with reduced integration - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-dual-scheme.md b/packages/akms/src/akms/_bundled/global_nodes/fft-dual-scheme.md deleted file mode 100644 index 018f34a..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-dual-scheme.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -id: fft-dual-scheme -title: Dual (Stress-Based) FFT Formulation -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- fft-galerkin -- spectral -- dual-formulation -- stress-based -- homogenization -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Dual scheme reformulates the Lippmann-Schwinger equation in stress space -- to: fft-green-operator - type: requires - weight: 1.0 - note: Uses the Green operator to project onto divergence-free stress fields -- to: fft-reference-medium - type: requires - weight: 0.9 - note: Reference compliance D0 = (C0)^{-1} controls convergence of the dual iteration -- to: fft-solver-basic-scheme - type: refines - weight: 0.9 - note: Dual basic scheme is the stress-space analog of the primal basic scheme -- to: fft-galerkin-basics - type: requires - weight: 0.8 - note: Dual scheme builds on the Galerkin framework with divergence-free test functions -context_size: medium -reading_priority: full -load_with: -- fft-lippmann-schwinger -- fft-solver-basic-scheme -- fft-reference-medium -content_ref: null -akms_schema: v2 ---- - -# Dual (Stress-Based) FFT Formulation - -## Summary -The dual (stress-based) FFT formulation reformulates the classical strain-based Lippmann-Schwinger equation into stress space, minimizing the Legendre-Fenchel dual energy over the space of equilibrated (divergence-free) stress fields. The primary unknown is the stress field rather than the strain field, and the formulation relies on the reference compliance tensor D0 = (C0)^{-1} instead of the reference stiffness. The dual scheme has two key practical advantages: it naturally handles perfectly rigid inclusions (characterized by vanishing compliance), and for constitutive models where computing strain from stress is cheaper than the reverse (e.g., certain crystal plasticity models), it can accelerate the solver by an order of magnitude. All solver families (basic scheme, Krylov, Newton) carry over to the dual setting with equivalent convergence guarantees. The main disadvantages are increased memory requirements (no reduced-memory displacement storage) and no benefit when combined with polarization methods which are inherently primal-dual. - - -## 1. Core Concept -The dual formulation rewrites the unconstrained primal variational principle (minimizing elastic energy over compatible strain fields) as a constrained optimization where the primary unknown is the equilibrated stress field $\boldsymbol{\sigma}$ belonging to the divergence-free space $S = \{\boldsymbol{\sigma} \in L^2(Y; \text{Sym}(d)) \mid \text{div}\,\boldsymbol{\sigma} = 0\}$. The standard free energy density $w(\mathbf{x}, \boldsymbol{\varepsilon})$ is replaced by its Legendre-Fenchel dual, the condensed Helmholtz free energy $w^*(\mathbf{x}, \boldsymbol{\sigma})$. Instead of the Green operator $\boldsymbol{\Gamma}^0$ projecting onto compatible strain fields, the dual formulation uses a complementary projection operator $(\mathbf{Id} - \boldsymbol{\Gamma}^0 \colon \mathbf{C}^0 - \frac{1}{\text{vol}(Y)} \int_Y \cdot\, dx)$ that projects onto the discretely divergence-free subspace. Every stress iterate automatically satisfies mechanical equilibrium, mirroring how every strain iterate in the primal scheme automatically satisfies compatibility. The dual framework is particularly suited for composites containing rigid phases, where the compliance vanishes but the stiffness is infinite. - - -## 2. Mathematical Formulation -The dual variational principle minimizes the Legendre-Fenchel dual energy over equilibrated stress fields. The dual basic scheme iteratively solves this by computing the dual strain polarization (difference between local strain from the dual potential and reference compliance response), then projecting it onto the divergence-free subspace using the complementary Green operator. - - -**Dual variational principle:** - -$$ -\int_Y w^*(\mathbf{x}, \boldsymbol{\sigma}) - \boldsymbol{\sigma} \colon \bar{\boldsymbol{\varepsilon}} \, d\mathbf{x} \longrightarrow \min_{\boldsymbol{\sigma} \in S} -$$ - -where w* is the condensed Helmholtz free energy (Legendre-Fenchel dual of w), S is the space of divergence-free stress fields, epsilon-bar is prescribed macroscopic strain - -**Divergence-free stress space:** - -$$ -S = \{\boldsymbol{\sigma} \in L^2(Y; \text{Sym}(d)) \mid \text{div}\,\boldsymbol{\sigma} = 0\} -$$ - -where Y is the periodic cell, Sym(d) is the space of symmetric second-order tensors in d dimensions - -**Dual basic scheme iteration:** - -$$ -\boldsymbol{\sigma}_{k+1} = \mathbf{C}^0 \colon \bar{\boldsymbol{\varepsilon}} + \mathbf{C}^0 \colon \left( \mathbf{Id} - \boldsymbol{\Gamma}^0 \colon \mathbf{C}^0 - \frac{1}{\text{vol}(Y)} \int_Y \cdot\, d\mathbf{x} \right) \colon \left( \frac{\partial w^*}{\partial \boldsymbol{\sigma}}(\cdot, \boldsymbol{\sigma}_k) - \mathbf{D}^0 \colon \boldsymbol{\sigma}_k \right) -$$ - -where C0 is reference stiffness, D0 = (C0)^{-1} is reference compliance, Gamma0 is the Green operator, dw*/dsigma evaluates local strain from dual potential - -**Divergence-free projection operator:** - -$$ -\mathbf{P}_S = \mathbf{Id} - \boldsymbol{\Gamma}^0 \colon \mathbf{C}^0 - \frac{1}{\text{vol}(Y)} \int_Y \cdot\, d\mathbf{x} -$$ - -where P_S projects fields into the discretely divergence-free subspace; complement of the compatibility projection - -**Reference compliance tensor:** - -$$ -\mathbf{D}^0 = (\mathbf{C}^0)^{-1} -$$ - -where D0 is the compliance of the reference medium; vanishes for rigid phases (infinite stiffness) making the dual scheme well-defined - -**Dual convergence criterion (compatibility residual):** - -$$ -\left\| \boldsymbol{\varepsilon}_k - \bar{\boldsymbol{\varepsilon}} - \boldsymbol{\Gamma} : \boldsymbol{\varepsilon}_k \right\|_{L^2} \leq \text{tol} \left\| \bar{\boldsymbol{\varepsilon}} \right\| -$$ - -where epsilon_k = dw*/dsigma(x, sigma_k) is the strain derived from the dual potential at iteration k, Gamma = nabla_s G div is the non-dimensional L2-orthogonal projection onto the space of compatible strain fields, epsilon_bar is the prescribed macroscopic strain; the term (epsilon_k - epsilon_bar - Gamma : epsilon_k) measures the incompatible part of the strain field - -**Non-dimensional projection operator (convergence evaluation):** - -$$ -\boldsymbol{\Gamma} = \nabla_s G \, \text{div}, \quad G = (\text{div}\,\nabla_s)^{-1} -$$ - -where Gamma is the L2-orthogonal projector onto compatible strain fields; in Fourier space hat{Gamma}_{ijkl}(xi) = (1/4)(delta_{ik} xi_j xi_l + delta_{jk} xi_i xi_l + delta_{jl} xi_i xi_k + delta_{il} xi_j xi_k) / |xi|^2, set to zero at xi=0 and Nyquist frequencies - -**Primal-dual duality of convergence criteria:** - -$$ -\text{Primal: } \| \text{div}\,\boldsymbol{\sigma} \|_{H^{-1}_\#} = \| \boldsymbol{\Gamma} : \boldsymbol{\sigma} \|_{L^2} \leq \text{tol} \left\| \langle \boldsymbol{\sigma} \rangle \right\|, \quad \text{Dual: } \left\| \boldsymbol{\varepsilon}_k - \bar{\boldsymbol{\varepsilon}} - \boldsymbol{\Gamma} : \boldsymbol{\varepsilon}_k \right\|_{L^2} \leq \text{tol} \left\| \bar{\boldsymbol{\varepsilon}} \right\| -$$ - -where The primal criterion checks equilibrium (div sigma = 0) while the dual criterion checks compatibility (epsilon is a symmetric gradient); both use the same non-dimensional Gamma operator - -**Notation:** - -- $w^*$ — Condensed Helmholtz free energy (Legendre-Fenchel dual of w) -- $\boldsymbol{\sigma}$ — Cauchy stress field (primary unknown in dual formulation) -- $S$ — Space of divergence-free (equilibrated) stress fields -- $\mathbf{D}^0$ — Reference compliance tensor, inverse of reference stiffness C0 -- $\mathbf{C}^0$ — Reference medium stiffness tensor -- $\boldsymbol{\Gamma}^0$ — Green operator of the reference medium -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain -- $\mathbf{P}_S$ — Projection operator onto divergence-free stress subspace -- $\boldsymbol{\Gamma}$ — Non-dimensional L2-orthogonal projection operator onto compatible strain fields; Gamma = nabla_s G div -- $\boldsymbol{\varepsilon}_k$ — Strain field at iteration k, derived from dual potential: epsilon_k = dw*/dsigma(x, sigma_k) - - -## 3. Algorithmic Implementation -**Algorithm: Dual Basic Scheme (Stress-Based Fixed-Point)** - -$$ -\begin{algorithmic} -\State $\boldsymbol{\sigma}_0(\mathbf{x}) \leftarrow \mathbf{C}^0 \colon \bar{\boldsymbol{\varepsilon}}$ -\While{$\left\| \boldsymbol{\varepsilon}_k - \bar{\boldsymbol{\varepsilon}} - \boldsymbol{\Gamma} \colon \boldsymbol{\varepsilon}_k \right\|_{L^2} > \text{tol} \left\| \bar{\boldsymbol{\varepsilon}} \right\|$} - \State $\boldsymbol{\varepsilon}_k(\mathbf{x}) \leftarrow \frac{\partial w^*}{\partial \boldsymbol{\sigma}}(\mathbf{x}, \boldsymbol{\sigma}_k(\mathbf{x}))$ - \State $\boldsymbol{\eta}_k(\mathbf{x}) \leftarrow \boldsymbol{\varepsilon}_k(\mathbf{x}) - \mathbf{D}^0 \colon \boldsymbol{\sigma}_k(\mathbf{x})$ - \State $\hat{\boldsymbol{\eta}}_k \leftarrow \text{DFT}(\boldsymbol{\eta}_k)$ - \State $\hat{\boldsymbol{\eta}}_k^S(\boldsymbol{\xi}) \leftarrow \hat{\boldsymbol{\eta}}_k(\boldsymbol{\xi}) - \hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) \colon \mathbf{C}^0 \colon \hat{\boldsymbol{\eta}}_k(\boldsymbol{\xi}) \quad \forall \boldsymbol{\xi} \neq \mathbf{0}$ - \State $\hat{\boldsymbol{\eta}}_k^S(\mathbf{0}) \leftarrow \mathbf{0}$ - \State $\boldsymbol{\eta}_k^S \leftarrow \text{DFT}^{-1}(\hat{\boldsymbol{\eta}}_k^S)$ - \State $\boldsymbol{\sigma}_{k+1}(\mathbf{x}) \leftarrow \mathbf{C}^0 \colon \bar{\boldsymbol{\varepsilon}} + \mathbf{C}^0 \colon \boldsymbol{\eta}_k^S(\mathbf{x})$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -The dual strain polarization eta_k is computed pointwise (Taichi kernel). Forward/inverse FFT via ti.fft. The divergence-free projection is a pointwise Fourier-space kernel applying (Id - Gamma0:C0). Stress update is a pointwise real-space kernel. The compatibility residual is evaluated in Fourier space via Parseval theorem: apply hat{Gamma}(xi) to hat{epsilon}_k(xi) at each frequency and sum squared magnitudes. - - -## 4. Known Pitfalls -**Increased memory footprint:** The dual scheme operates on stress fields, preventing the reduced-memory implementations available in the primal scheme. In the primal formulation, memory can be drastically reduced by storing scalar displacement fields instead of full strain tensors. The dual scheme cannot exploit this because equilibrated stress fields do not have an analogous compact representation. - - -**No benefit with polarization methods:** Polarization-based solvers (Eyre-Milton, ADMM) are inherently primal-dual methods that operate on a combined stress-strain polarization field. There is no advantage to a dual formulation when using these solvers, as they already incorporate both stress and strain information by construction. - - -**Convergence criterion not equilibrium-based:** Unlike the primal scheme where the equilibrium residual (divergence of stress) serves as the natural convergence criterion, the dual scheme automatically satisfies equilibrium at every iterate. The convergence must instead be assessed through the compatibility of the resulting strain field: the incompatible part $\|\boldsymbol{\varepsilon}_k - \bar{\boldsymbol{\varepsilon}} - \boldsymbol{\Gamma} : \boldsymbol{\varepsilon}_k\|_{L^2}$ is measured using the non-dimensional projection operator $\boldsymbol{\Gamma} = \nabla_s G \text{div}$. This mirrors the primal criterion $\|\boldsymbol{\Gamma} : \boldsymbol{\sigma}\|_{L^2}$ but swaps equilibrium for compatibility. The residual is evaluated in Fourier space using $\hat{\boldsymbol{\Gamma}}(\boldsymbol{\xi})$ and Parseval's theorem. - - -**Limited to constitutive models with accessible dual potential:** The dual scheme requires evaluation of the Legendre-Fenchel dual energy $w^*(\mathbf{x}, \boldsymbol{\sigma})$ and its derivative (strain as a function of stress). For constitutive models where the stress-to-strain mapping is not analytically available or is computationally expensive, the dual scheme loses its advantage over the primal formulation. - - -## 5. References -- Schneider (2021) — Review of nonlinear FFT-based computational homogenization, dual formulation and stress-based iteration -- Bhattacharya, Suquet (2005) — Dual variational principle for FFT-based homogenization - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-finite-strain.md b/packages/akms/src/akms/_bundled/global_nodes/fft-finite-strain.md deleted file mode 100644 index e823a6e..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-finite-strain.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -id: fft-finite-strain -title: FFT at Finite Strains -domain: fft-galerkin -subdomain: coupled-problems -tags: -- fft-galerkin -- finite-strain -- homogenization -- spectral -- continuum-mechanics -- newton -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Finite-strain Lippmann-Schwinger equation generalizes the small-strain form -- to: fft-green-operator - type: requires - weight: 0.9 - note: Finite-strain Green's operator loses minor symmetries compared to small-strain -- to: fft-reference-medium - type: requires - weight: 0.8 - note: Isotropic reference K0 = alpha0 I preferred at finite strains to commute with non-symmetric tangents -- to: fft-solver-newton-krylov - type: feeds-into - weight: 0.9 - note: Newton-Krylov is near-mandatory at finite strains due to poor basic scheme convergence -- to: fft-solver-basic-scheme - type: feeds-into - weight: 0.6 - note: Basic scheme can serve as inner solver for Newton linearization at finite strains -- to: fft-polycrystal - type: feeds-into - weight: 0.7 - note: Finite-strain framework used in polycrystal simulations with multiplicative decomposition -- to: kinematics-multiplicative-decomp - type: requires - weight: 0.7 - note: Multiplicative decomposition F=FeFp is the standard kinematics for finite-strain plasticity -context_size: large -reading_priority: full -load_with: -- fft-lippmann-schwinger -- fft-solver-newton-krylov -content_ref: null -akms_schema: v2 ---- - -# FFT at Finite Strains - -## Summary -FFT-based homogenization at finite strains reformulates the Lippmann-Schwinger framework in a total Lagrangian setting using the deformation gradient $\mathbf{F}$ and the first Piola-Kirchhoff stress $\mathbf{P}$ instead of the small-strain $\boldsymbol{\varepsilon}$ and $\boldsymbol{\sigma}$. The governing equilibrium is $\nabla_0 \cdot \mathbf{P}(\mathbf{X}) = 0$ with periodicity of $\mathbf{F}$ and average $\langle \mathbf{F} \rangle = \bar{\mathbf{F}}$. The finite-strain Green's operator $\hat{\Gamma}^0_f$ loses minor symmetries, and the material tangent $\mathbf{K} = \partial\mathbf{P}/\partial\mathbf{F}$ is fundamentally non-symmetric. This prevents use of CG (requiring GMRES instead), inflates memory from 21 to 36 tangent components per voxel, and makes Newton-Raphson with globalization near-mandatory because the basic scheme converges poorly. Three main algorithmic approaches exist: the basic scheme adapted for F and P, Newton-Raphson with the basic scheme as inner solver (Lahellec et al.), and the displacement-based DBFFT approach with preconditioning. - - -## 1. Core Concept -In the finite-strain total Lagrangian framework for FFT homogenization, equilibrium is formulated on the reference configuration using the first Piola-Kirchhoff stress $\mathbf{P}$ and the deformation gradient $\mathbf{F}$. The local deformation gradient $\mathbf{F}(\mathbf{X})$ replaces the small-strain tensor $\boldsymbol{\varepsilon}$ as the primary kinematic unknown and is decomposed into the macroscopic average $\bar{\mathbf{F}}$ and a periodic fluctuation $\tilde{\mathbf{F}}(\mathbf{X})$. By introducing a reference material tangent $\mathbf{K}_0$, the equilibrium can be transformed into a finite-strain Lippmann-Schwinger integral equation. The key complications relative to small strains are: (1) the modified Green's operator $\hat{\Gamma}^0_f$ only possesses major tensor symmetries, not minor ones, (2) the material tangent $\mathbf{K} = \partial\mathbf{P}/\partial\mathbf{F}$ is non-symmetric, preventing use of CG solvers, and (3) the basic scheme converges poorly because geometric nonlinearity is added to the implicit equation without tangent information. - - -## 2. Mathematical Formulation -The finite-strain framework operates on the reference configuration with the equilibrium $\nabla_0 \cdot \mathbf{P} = 0$ subject to periodicity of $\mathbf{F}$ and prescribed macroscopic average $\bar{\mathbf{F}}$. The Lippmann-Schwinger equation is written in Fourier space using a finite-strain Green's operator. The basic scheme iteration adapts directly by replacing $\boldsymbol{\varepsilon}$ with $\mathbf{F}$ and $\boldsymbol{\sigma}$ with $\mathbf{P}$. Newton linearization introduces the non-symmetric tangent $\mathbf{K}_i$ and requires globalization via line search. - - -**Finite-strain equilibrium:** - -$$ -\nabla_0 \cdot \mathbf{P}(\mathbf{X}) = 0, \quad \langle \mathbf{F} \rangle = \bar{\mathbf{F}}, \quad \mathbf{F} \text{ periodic} -$$ - -where P is the first Piola-Kirchhoff stress, F is the deformation gradient, F_bar is the prescribed macroscopic deformation gradient - -**Finite-strain Lippmann-Schwinger equation in Fourier space:** - -$$ -\hat{\mathbf{F}}(\boldsymbol{\xi}) = \bar{\mathbf{F}} - \hat{\Gamma}^0_f(\boldsymbol{\xi}) : (\hat{\mathbf{P}}(\boldsymbol{\xi}) - \mathbf{K}_0 : \hat{\mathbf{F}}(\boldsymbol{\xi})) -$$ - -where Gamma^0_f is the finite-strain Green's operator, K_0 is the reference material tangent, xi is the frequency vector - -**Finite-strain Green's operator (Fourier space):** - -$$ -\hat{\Gamma}^0_{f\,ijkl}(\boldsymbol{\xi}) = \hat{G}^0_{ik}(\boldsymbol{\xi})\,\xi_j\,\xi_l -$$ - -where G^0 is the Green's function (acoustic tensor inverse of the reference medium); only major symmetries are preserved, minor symmetries are lost - -**Newton linearization of first Piola-Kirchhoff stress:** - -$$ -\mathbf{P}_{i+1} = \mathbf{P}_i + \frac{\partial \mathbf{P}}{\partial \mathbf{F}}\bigg|_{\mathbf{F}_i} : \delta\mathbf{F} = \mathbf{P}_i + \mathbf{K}_i : \delta\mathbf{F} -$$ - -where K_i = dP/dF at F_i is the non-symmetric material tangent at Newton iteration i, delta F is the deformation gradient correction - -**Basic scheme iteration at finite strains:** - -$$ -\hat{\mathbf{F}}_{k+1}(\boldsymbol{\xi}) = \bar{\mathbf{F}} - \hat{\Gamma}^0_f(\boldsymbol{\xi}) : \hat{\boldsymbol{\tau}}_k(\boldsymbol{\xi}) -$$ - -where tau_k(X) = P(F_k(X)) - K_0 : F_k(X) is the stress polarization at iteration k - -**DBFFT Newton linearized system:** - -$$ -\mathbf{M} \cdot \hat{\nabla} : \mathcal{F}\left\{\mathbf{K}_i : \left(\mathcal{F}^{-1}\left\{\hat{\nabla} \cdot \delta\hat{\tilde{\mathbf{u}}}\right\}\right)\right\} = -\mathbf{M} \cdot \hat{\nabla} : \mathcal{F}\{\mathbf{P}_i\} -$$ - -where M is the preconditioner based on the average tangent, u_tilde is the displacement fluctuation, nabla_hat is the Fourier gradient operator - -**Notation:** - -- $\mathbf{F}$ — Deformation gradient (non-symmetric second-order tensor) -- $\mathbf{P}$ — First Piola-Kirchhoff stress tensor -- $\mathbf{K}$ — Material tangent dP/dF (non-symmetric fourth-order tensor) -- $\mathbf{K}_0$ — Reference material tangent stiffness -- $\hat{\Gamma}^0_f$ — Finite-strain Green's operator in Fourier space (only major symmetries) -- $\bar{\mathbf{F}}$ — Prescribed macroscopic deformation gradient -- $\delta\mathbf{F}$ — Newton correction to the deformation gradient - - -## 3. Algorithmic Implementation -**Algorithm: Basic Scheme at Finite Strains** - -$$ -\begin{algorithmic} -\State $Initialize \colon \mathbf{F}_0(\mathbf{X}) = \bar{\mathbf{F}}, \; \mathbf{K}_0 = \alpha_0 \mathbf{I}$ -\While{$\|\boldsymbol{\xi} \cdot \hat{\mathbf{P}}_k\|_\infty / \|\hat{\mathbf{P}}_k(\mathbf{0})\| > \mathrm{tol}$} - \State $\mathbf{P}_k(\mathbf{X}) = \mathbf{P}(\mathbf{F}_k(\mathbf{X})) \quad \text{(constitutive evaluation)}$ - \State $\hat{\boldsymbol{\tau}}_k(\boldsymbol{\xi}) = \mathcal{F}\{\mathbf{P}_k(\mathbf{X}) - \mathbf{K}_0 \colon \mathbf{F}_k(\mathbf{X})\}$ - \State $\hat{\mathbf{F}}_{k+1}(\boldsymbol{\xi}) = \bar{\mathbf{F}} - \hat{\Gamma}^0_f(\boldsymbol{\xi}) \colon \hat{\boldsymbol{\tau}}_k(\boldsymbol{\xi})$ - \State $\mathbf{F}_{k+1}(\mathbf{X}) = \mathcal{F}^{-1}\{\hat{\mathbf{F}}_{k+1}(\boldsymbol{\xi})\}$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -Each voxel constitutive evaluation P(F) maps to a parallel GPU kernel. FFT/iFFT via cuFFT. The non-symmetric stress polarization and Green's operator application are local per-voxel operations. Poor convergence makes this approach impractical for large-strain increments. - -**Algorithm: Newton-Raphson with Basic Scheme as Inner Solver (Lahellec)** - -$$ -\begin{algorithmic} -\State $Initialize \colon \mathbf{F}_0 = \mathbf{F}_t + \Delta\mathbf{F}_{t+\Delta t}$ -\While{$\|\boldsymbol{\xi} \cdot \hat{\mathbf{P}}_i(\boldsymbol{\xi})\|_\infty / \|\hat{\mathbf{P}}_i(\mathbf{0})\| > \mathrm{tol}_{\mathrm{nw}}$} - \State $\mathbf{P}_i = \mathbf{P}(\mathbf{F}_i), \quad \mathbf{K}_i = \frac{\partial \mathbf{P}}{\partial \mathbf{F}}\bigg|_{\mathbf{F}_i}$ - \State $\text{Inner solve (basic scheme to tol}_{lin}\text{)} \colon \delta\hat{\mathbf{F}}_{j+1} = -\hat{\Gamma}^0_f \colon [\mathcal{F}\{\mathbf{K}_i \colon \delta\mathbf{F}_j\} + \hat{\mathbf{P}}_i]$ - \State $\mathbf{F}_{i+1} = \mathbf{F}_i + \delta\mathbf{F}$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -Outer Newton loop on host. Inner basic scheme iterations on GPU. Tangent K_i stored as 9x9 non-symmetric matrix per voxel (36 doubles). At 512^3 voxels, tangent storage alone exceeds 30 GB in double precision. - - -## 4. Known Pitfalls -**Non-symmetric tangent forces GMRES over CG:** The material tangent $\mathbf{K} = \partial\mathbf{P}/\partial\mathbf{F}$ is fundamentally non-symmetric at finite strains, preventing use of CG which requires symmetric positive-definite operators. GMRES or Bi-CGStab must be used instead, both of which are more expensive per iteration and require more storage for the Krylov basis vectors. - - -**Massive memory inflation from non-symmetric tensors:** The non-symmetric tangent requires storing 36 independent components per voxel instead of 21 for the symmetric small-strain tangent. For a $512^3$ grid in double precision, this increases tangent storage from 21 GB to over 30 GB. Combined with the additional strain fields needed by Krylov solvers, total memory can exceed 60 GB, making Newton-Krylov at finite strains prohibitively expensive for high-resolution microstructures. - - -**Poor convergence of the basic scheme:** Direct extension of the Moulinec-Suquet basic scheme to finite strains adds geometric nonlinearity to the implicit Lippmann-Schwinger equation without using tangent information. The convergence rate is drastically worse than in the small-strain case, making Newton-Raphson with globalization (back-tracking line search) near-mandatory for practical computations. - - -**Reference medium must be isotropic at finite strains:** The finite-strain Green's operator $\hat{\Gamma}^0_f$ loses minor symmetries. To ensure the reference medium commutes with all local non-symmetric tangents across the microstructure, the standard practice is to choose an isotropic reference $\mathbf{K}_0 = \alpha_0 \mathbf{I}$ proportional to the identity tensor. Anisotropic reference stiffnesses, while theoretically yielding linear convergence, are highly inefficient. - - -**Rotation overhead for anisotropic constitutive laws:** Finite-strain simulations of anisotropic materials (e.g., polycrystals) require continuously tracking the rotation of the crystal lattice. This introduces a time-consuming rotation step at each voxel during constitutive evaluation that is absent in isotropic or small-strain simulations. - - -## 5. References -- Schneider (2021) -- Finite-strain FFT formulation, basic scheme extension, reference medium selection -- Lahellec et al. (2003) -- Newton-Raphson with basic scheme as inner solver for finite strains -- Lucarini et al. (2022) -- DBFFT displacement-based formulation at finite strains, preconditioning -- Kabel et al. (2014) -- Newton-CG for finite-strain FFT, memory cost analysis - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-freq-grid.md b/packages/akms/src/akms/_bundled/global_nodes/fft-freq-grid.md deleted file mode 100644 index be781b4..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-freq-grid.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -id: fft-freq-grid -title: Frequency Grid & Nyquist Treatment -domain: fft-galerkin -subdomain: spectral-foundations -tags: -- freq-grid -- fft-galerkin -- spectral -- discretization -- periodic-bc -- homogenization -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-galerkin-basics - type: requires - weight: 1.0 - note: Frequency grid is the fundamental discrete domain on which all Fourier-space operations are defined -- to: fft-green-operator - type: feeds-into - weight: 1.0 - note: Green's operator is evaluated pointwise on the frequency grid; Nyquist treatment directly affects operator symmetry -- to: fft-discretization-moulinec-suquet - type: feeds-into - weight: 0.9 - note: Moulinec-Suquet basic scheme iterates on the frequency grid using continuous frequency vectors -- to: fft-discretization-willot - type: feeds-into - weight: 0.8 - note: Willot's scheme modifies the frequency vector but operates on the same grid -- to: fft-discretization-staggered - type: feeds-into - weight: 0.8 - note: Staggered grid uses modified frequency vector defined on this grid -- to: fft-discretization-fd-highorder - type: feeds-into - weight: 0.8 - note: Higher-order FD schemes define trigonometric frequency vectors on this grid -- to: fft-solver-basic-scheme - type: feeds-into - weight: 0.7 - note: Basic scheme iteration alternates between real-space grid and frequency grid via DFT/IDFT -context_size: medium -reading_priority: full -load_with: -- fft-galerkin-basics -- fft-green-operator -content_ref: null -akms_schema: v2 ---- - -# Frequency Grid & Nyquist Treatment - -## Summary -The frequency grid defines the discrete set of integer frequency vectors on which all Fourier-space operations in FFT-based homogenization are performed. For a computational cell of dimensions $L_1 \times \ldots \times L_d$ discretized into $N_1 \times \ldots \times N_d$ voxels, the integer frequencies range from $-N_j/2$ to $N_j/2 - 1$ in each direction. The re-scaled frequency vector maps these integers to physical frequencies via $\xi_{Y,j} = 2\pi\xi_j/L_j$. Critical to correct implementation is the treatment of the Nyquist frequency ($\xi_j = -N_j/2$) on even grids, where Fourier operator symmetries are lost and artificial zeroing or redefinition of operators is required to ensure real-valued solution fields. - - -## 1. Core Concept -The discrete Fourier transform (DFT) maps voxel-grid fields to a finite set of complex-valued Fourier coefficients indexed by integer frequency vectors $\boldsymbol{\xi} \in Z_N$. The integer frequency set $Z_N$ is bounded by the voxel counts: $-N_j/2 \le \xi_j < N_j/2$. The physical frequency content is captured by the re-scaled frequency vector $\boldsymbol{\xi}_Y$ which accounts for the cell dimensions. All Fourier-space operators (Green's operator, projection operators, finite-difference frequency multipliers) are evaluated pointwise on $Z_N$. Two special frequencies require dedicated handling: the zero frequency $\boldsymbol{\xi} = \mathbf{0}$ (which carries the macroscopic average and must be prescribed, not computed) and the Nyquist frequencies (which exist only on even grids and break the tensor symmetries of Fourier operators). The choice between even and odd grid sizes affects whether Nyquist treatment is needed at all. - - -## 2. Mathematical Formulation -The frequency grid is defined by the integer frequency set $Z_N$, the real-space voxel grid $Y_N$, and the re-scaled frequency vector $\boldsymbol{\xi}_Y$ that connects the two. The DFT and its inverse map fields between these grids. The Nyquist frequencies form a special subset where operator symmetries break down. - - -**Integer frequency set:** - -$$ -Z_N = \left\{ \boldsymbol{\xi} \in \mathbb{Z}^d \;\middle|\; -N_j/2 \le \xi_j < N_j/2 \;\text{for all}\; j = 1, \ldots, d \right\} -$$ - -where N_j is the number of voxels in direction j, d is the spatial dimension - -**Real-space voxel grid:** - -$$ -Y_N = \left\{ \mathbf{x} \in Y \;\middle|\; x_j = I_j L_j / N_j \;\text{for all}\; j = 1, \ldots, d \;\text{and some}\; \mathbf{I} \in \mathcal{I}_N \right\} -$$ - -where I_j are integer indices, L_j are cell dimensions, Y is the periodic cell - -**Re-scaled frequency vector:** - -$$ -\boldsymbol{\xi}_Y = \left( \frac{2\pi \xi_1}{L_1}, \frac{2\pi \xi_2}{L_2}, \ldots, \frac{2\pi \xi_d}{L_d} \right) -$$ - -where xi_j are integer frequency indices, L_j are cell dimensions - -**Discrete Fourier transform:** - -$$ -\hat{\boldsymbol{\tau}}(\boldsymbol{\xi}) = \frac{1}{N_1 \cdots N_d} \sum_{\mathbf{I} \in Y_N} \boldsymbol{\tau}(\mathbf{x}_\mathbf{I}) \, e^{-i\, \mathbf{x}_\mathbf{I} \cdot \boldsymbol{\xi}_Y}, \quad \boldsymbol{\xi} \in Z_N -$$ - -where The phase product x_I . xi_Y = 2pi sum_j I_j xi_j / N_j is independent of cell dimensions L_j - -**Nyquist frequency set:** - -$$ -\mathcal{N} = \left\{ \boldsymbol{\xi} \in \mathbb{Z}^d \;\middle|\; \xi_j = -N_j/2 \;\text{for some}\; j = 1, \ldots, d \right\} -$$ - -where These frequencies exist only when N_j is even - -**Nyquist treatment option 1 (zero strain coefficients):** - -$$ -\hat{\boldsymbol{\varepsilon}}(\boldsymbol{\xi}) = \mathbf{0} \quad \text{for all } \boldsymbol{\xi} \in \mathcal{N} -$$ - -where Forces the Fourier coefficients of the strain field to zero at Nyquist frequencies - -**Nyquist treatment option 2 (zero stress coefficients):** - -$$ -\hat{\boldsymbol{\varepsilon}}(\boldsymbol{\xi}) = -(\mathbf{C}^0)^{-1} \colon \hat{\boldsymbol{\tau}}(\boldsymbol{\xi}) \quad \text{for all } \boldsymbol{\xi} \in \mathcal{N} -$$ - -where Forces the Fourier coefficients of the stress field to zero at Nyquist by setting varepsilon = -(C0)^{-1} colon tau - -**Frequency reordering for numerical implementations:** - -$$ -q = \begin{cases} 0, 1, 2, \ldots, \frac{N-1}{2}, -\frac{N-1}{2}, -\frac{N-1}{2}+1, \ldots, -1 & \text{if } N \text{ even} \\ 0, 1, 2, \ldots, \frac{N}{2}, -\frac{N}{2}+1, -\frac{N}{2}+2, \ldots, -1 & \text{if } N \text{ odd} \end{cases} -$$ - -where Standard frequency reordering used in numerical FFT libraries to center the spectrum around zero - -**Notation:** - -- $Z_N$ — Set of integer frequency d-tuples -- $Y_N$ — Set of real-space voxel grid points -- $\boldsymbol{\xi}$ — Integer frequency vector -- $\boldsymbol{\xi}_Y$ — Re-scaled frequency vector incorporating cell dimensions -- $\mathcal{N}$ — Nyquist frequency set -- $N_j$ — Number of voxels in direction j -- $L_j$ — Cell dimension in direction j -- $\mathbf{C}^0$ — Reference medium stiffness tensor - - -## 3. Algorithmic Implementation -Not applicable as a standalone algorithm. The frequency grid is a data structure, not a procedure. Its construction and Nyquist treatment are embedded as initialization steps within all FFT-based solvers (see fft-solver-basic-scheme and related nodes). - -## 4. Known Pitfalls -**Complex-valued fields from unhandled Nyquist frequencies:** On even grids, the Fourier projection operator loses its tensor symmetries at the Nyquist frequency $\xi_j = -N_j/2$. If the operator is not explicitly zeroed or redefined at these frequencies, the inverse DFT will produce fields with spurious imaginary components. This is a common implementation bug that manifests as complex-valued stress or strain fields that should be purely real. - - -**Even vs odd grid parity choice:** Odd grids ($N_j$ odd) avoid the Nyquist frequency issue entirely because the integer range $-(N_j-1)/2$ to $(N_j-1)/2$ is symmetric and never hits the $-N_j/2$ boundary. Some practitioners deliberately choose odd grid sizes to sidestep Nyquist treatment, but this limits grid sizes (e.g., cannot use power-of-two grids that are optimal for FFT performance). Even grids require explicit Nyquist handling but allow optimal FFT sizes. - - -**Zero-frequency handling:** The Green's operator formula involves division by $\|\boldsymbol{\xi}_Y\|^2$, which is singular at $\boldsymbol{\xi} = \mathbf{0}$. The zero frequency carries the macroscopic average strain $\bar{\boldsymbol{\varepsilon}}$, which is prescribed as input, not computed by the Green's operator. All operator formulas must explicitly exclude $\boldsymbol{\xi} = \mathbf{0}$ and set $\hat{\boldsymbol{\varepsilon}}(\mathbf{0}) = \bar{\boldsymbol{\varepsilon}}$. - - -**Aliasing from DFT approximation of continuous Fourier transform:** Substituting the continuous Fourier transform with the DFT introduces aliasing because only a finite number of frequencies are represented. For piecewise-constant voxel fields, the exact Fourier transform involves a sinc-weighted DFT, not the raw DFT. Using the raw DFT to approximate spatial derivatives introduces high-frequency noise and Gibbs phenomena (ringing artifacts). This aliasing is particularly severe at sharp material interfaces. - - -**Cell-dimension independence of phase product:** The DFT phase product $\mathbf{x}_\mathbf{I} \cdot \boldsymbol{\xi}_Y = 2\pi \sum_j I_j \xi_j / N_j$ is independent of the physical cell dimensions $L_j$. This means the DFT itself is purely a function of the grid resolution $N_j$, while the cell dimensions $L_j$ enter only through the re-scaled frequency vector in operator evaluations. Incorrectly incorporating $L_j$ into the DFT phase computation is a subtle but critical bug. - - -## 5. References -- Schneider (2021) — Frequency grid construction, DFT definition, and Nyquist treatment in FFT-based homogenization -- Lucarini, Segurado, et al. (2022) — DFT discretization, frequency reordering, and aliasing effects in FFT homogenization -- Moulinec and Suquet (1998) — Original Nyquist frequency treatment and odd-grid operator redefinition - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-galerkin-basics.md b/packages/akms/src/akms/_bundled/global_nodes/fft-galerkin-basics.md deleted file mode 100644 index 809e26e..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-galerkin-basics.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -id: fft-galerkin-basics -title: Fourier-Galerkin Discretization -domain: fft-galerkin -subdomain: discretization -tags: -- fft-galerkin -- spectral -- discretization -- homogenization -- periodic-bc -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-lippmann-schwinger - type: refines - weight: 0.8 - note: Galerkin approach bypasses Lippmann-Schwinger by working directly from the weak form -- to: fft-freq-grid - type: requires - weight: 0.9 - note: Requires the discrete frequency grid Z_N and re-scaled frequency vectors -- to: fft-green-operator - type: requires - weight: 0.7 - note: Projection operator is mathematically equivalent to the continuous Green's operator derivative -- to: fft-discretization-moulinec-suquet - type: refines - weight: 0.8 - note: Galerkin uses projection operator P_N vs Moulinec-Suquet's interpolation operator Q_N -- to: fft-convergence-schemes - type: feeds-into - weight: 0.6 - note: Galerkin linear system is solved via conjugate gradient or other Krylov solvers -- to: fft-discretization-fem - type: feeds-into - weight: 0.7 - note: FEM-based FFT is an alternative discretization of the Galerkin framework -context_size: large -reading_priority: full -load_with: -- fft-freq-grid -- fft-discretization-moulinec-suquet -content_ref: null -akms_schema: v2 ---- - -# Fourier-Galerkin Discretization - -## Summary -The Fourier-Galerkin discretization derives directly from the weak formulation of mechanical equilibrium (the principle of virtual work) without reformulating the problem into a Lippmann-Schwinger integral equation and without introducing a fictitious reference medium. The approximation spaces for test and trial functions are spanned entirely by trigonometric polynomials, and a symmetric projection operator enforces field compatibility in Fourier space. The resulting Galerkin linear system is rank-deficient but symmetric positive-definite on compatible strain fields, making it well-suited for conjugate gradient solvers. A key theoretical advantage is that the method generates rigorous upper bounds on effective elastic properties. However, the approach suffers from Gibbs ringing at material interfaces, fails for porous materials, and requires expensive Fourier-space convolutions for the constitutive law, limiting it to linear materials without additional Newton linearization. - - -## 1. Core Concept -The Fourier-Galerkin discretization is a true Galerkin method for FFT-based computational homogenization where the continuous variational principle is evaluated exactly on a restricted subspace of global trigonometric polynomials. Unlike the Moulinec-Suquet collocation approach that interpolates fields at grid points via the operator $Q_N$, the Fourier-Galerkin method projects fields onto trigonometric polynomial space via an orthogonal projection operator $P_N$. This projection solves a regression problem that minimizes the $L^2$ error of the fields. Because the method works directly from the weak form of equilibrium, it does not require a fictitious reference medium $\mathbf{C}^0$, and the constitutive behavior must be projected into Fourier space, requiring explicit knowledge of the Fourier coefficients of the stiffness field. The exact integration over the trigonometric polynomial basis naturally generates a hierarchy of rigorous upper bounds (and, via dualization, lower bounds) on the effective elastic properties. - - -## 2. Mathematical Formulation -The Fourier-Galerkin discretization relies on a symmetric trigonometric projection operator $\hat{\mathbf{G}}^s$ derived from the curl-free component of the Helmholtz decomposition. This operator enforces compatibility of virtual strain fields in Fourier space. The discrete Galerkin linear system is obtained by applying this projection to the stress computed from the constitutive law. The total strain is decomposed as $\boldsymbol{\varepsilon}(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}} + \tilde{\boldsymbol{\varepsilon}}(\mathbf{x})$ where $\bar{\boldsymbol{\varepsilon}}$ is the prescribed macroscopic strain and $\tilde{\boldsymbol{\varepsilon}}$ is the periodic fluctuation. The frequency grid is $Z_N = \{ \boldsymbol{\xi} \in \mathbb{Z}^d \mid -N_j/2 \le \xi_j < N_j/2 \}$ with re-scaled frequency vector $\boldsymbol{\xi}_Y = (2\pi\xi_1/L_1, \ldots, 2\pi\xi_d/L_d)$. - - -**Trigonometric projection operator (unsymmetrized):** - -$$ -\hat{G}_{ijkl}(\boldsymbol{\xi}) = \delta_{ik} \frac{\xi_j \xi_l}{\boldsymbol{\xi} \cdot \boldsymbol{\xi}}, \quad \boldsymbol{\xi} \neq \mathbf{0} -$$ - -where delta_ik is the Kronecker delta, xi are discrete frequency components - -**Symmetrized projection operator:** - -$$ -\hat{G}^s_{ijkl} = \frac{1}{4}(\hat{G}_{ijkl} + \hat{G}_{jikl} + \hat{G}_{jilk} + \hat{G}_{ijlk}) -$$ - -where Enforces minor symmetries of the strain tensor; set to zero at xi=0 and Nyquist frequencies - -**Galerkin linear system:** - -$$ -\hat{\mathbf{G}}^s(\boldsymbol{\xi}) : \mathcal{F}\{\mathbf{C}(\mathbf{x}) : \tilde{\boldsymbol{\varepsilon}}(\mathbf{x})\} -= -\hat{\mathbf{G}}^s(\boldsymbol{\xi}) : \mathcal{F}\{\mathbf{C}(\mathbf{x}) : \bar{\boldsymbol{\varepsilon}}\} -$$ - -where C(x) is local stiffness, F denotes Fourier transform, eps_tilde is strain fluctuation, eps_bar is macroscopic strain - -**Compact linear operator form:** - -$$ -A(\tilde{\boldsymbol{\varepsilon}}) = \mathbf{b}, \quad -A(\tilde{\boldsymbol{\varepsilon}}) = \mathcal{F}^{-1}\{ \hat{\mathbf{G}}^s : \mathcal{F}\{\mathbf{C} : \tilde{\boldsymbol{\varepsilon}}\} \}, \quad -\mathbf{b} = -\mathcal{F}^{-1}\{ \hat{\mathbf{G}}^s : \mathcal{F}\{\mathbf{C} : \bar{\boldsymbol{\varepsilon}}\} \} -$$ - -where A is symmetric positive-definite on compatible strain fields; solved via conjugate gradient - -**Galerkin variational balance (nonlinear extension):** - -$$ -\text{div}\, \mathbf{P}_N \left[ \frac{\partial w}{\partial \boldsymbol{\varepsilon}}(\cdot, \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_N) \right] = \mathbf{0} -$$ - -where P_N is the orthogonal trigonometric projection operator, w is local free energy density, u_N is the displacement fluctuation - -**Linearized Newton system for nonlinear extension:** - -$$ -\mathcal{F}^{-1}\{ \hat{\mathbf{G}} : \mathcal{F}\{ K_i : \delta\mathbf{F} \} \} -= -\mathcal{F}^{-1}\{ \hat{\mathbf{G}} : \mathcal{F}\{ \mathbf{P}_i \} \} -$$ - -where K_i is the local consistent tangent at Newton iteration i, P_i is first Piola-Kirchhoff stress, delta F is the deformation gradient correction - -**Notation:** - -- $\hat{\mathbf{G}}^s$ — Symmetrized trigonometric projection operator in Fourier space -- $\hat{G}_{ijkl}$ — Components of the unsymmetrized projection operator -- $\boldsymbol{\xi}$ — Discrete frequency vector in Z_N -- $\boldsymbol{\xi}_Y$ — Re-scaled frequency vector accounting for cell dimensions -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain -- $\tilde{\boldsymbol{\varepsilon}}$ — Periodic strain fluctuation field -- $\mathbf{C}(\mathbf{x})$ — Local stiffness tensor -- $\mathbf{P}_N$ — Orthogonal trigonometric projection operator truncating to Z_N -- $Q_N$ — Trigonometric interpolation (collocation) operator of Moulinec-Suquet -- $T_N$ — Space of trigonometric polynomials of order N -- $w$ — Local condensed free energy density -- $K_i$ — Local consistent tangent at Newton iteration i -- $Z_N$ — Discrete frequency set: {xi in Z^d | -N_j/2 <= xi_j < N_j/2} -- $Y_N$ — Discrete regular spatial grid -- $\mathcal{F}$ — Discrete Fourier Transform (DFT) - - -## 3. Algorithmic Implementation -**Algorithm: Algorithm** - -$$ -\begin{algorithmic} -\State $\text{Set up frequency grid } Z_N = \{ \boldsymbol{\xi} \in \mathbb{Z}^d \mid -N_j/2 \le \xi_j < N_j/2 \}$ -\State $\text{Compute } \hat{G}^s_{ijkl}(\boldsymbol{\xi}) = \frac{1}{4}(\delta_{ik}\frac{\xi_j\xi_l}{\boldsymbol{\xi}\cdot\boldsymbol{\xi}} + \delta_{jk}\frac{\xi_i\xi_l}{\boldsymbol{\xi}\cdot\boldsymbol{\xi}} + \delta_{jl}\frac{\xi_i\xi_k}{\boldsymbol{\xi}\cdot\boldsymbol{\xi}} + \delta_{il}\frac{\xi_j\xi_k}{\boldsymbol{\xi}\cdot\boldsymbol{\xi}}) \text{ for } \boldsymbol{\xi} \neq \mathbf{0}$ -\State $\hat{G}^s_{ijkl}(\mathbf{0}) = 0, \quad \hat{G}^s_{ijkl}(\boldsymbol{\xi}_{\text{Nyquist}}) = 0$ -\State $\mathbf{b}(\mathbf{x}) \gets -\mathcal{F}^{-1}\{ \hat{\mathbf{G}}^s(\boldsymbol{\xi}) \colon \mathcal{F}\{\mathbf{C}(\mathbf{x}) \colon \bar{\boldsymbol{\varepsilon}}\} \}$ -\State $\tilde{\boldsymbol{\varepsilon}}^{(0)}(\mathbf{x}) \gets \mathbf{0}, \quad \mathbf{r}^{(0)} \gets \mathbf{b} - A(\tilde{\boldsymbol{\varepsilon}}^{(0)}), \quad \mathbf{p}^{(0)} \gets \mathbf{r}^{(0)}$ -\While{$$} -\State $\mathbf{q}^{(k)} \gets A(\mathbf{p}^{(k)}) = \mathcal{F}^{-1}\{ \hat{\mathbf{G}}^s \colon \mathcal{F}\{\mathbf{C} \colon \mathbf{p}^{(k)}\} \}$ -\State $\alpha_k \gets \frac{\mathbf{r}^{(k)} \cdot \mathbf{r}^{(k)}}{\mathbf{p}^{(k)} \cdot \mathbf{q}^{(k)}}$ -\State $\tilde{\boldsymbol{\varepsilon}}^{(k+1)} \gets \tilde{\boldsymbol{\varepsilon}}^{(k)} + \alpha_k \mathbf{p}^{(k)}$ -\State $\mathbf{r}^{(k+1)} \gets \mathbf{r}^{(k)} - \alpha_k \mathbf{q}^{(k)}$ -\State $\beta_k \gets \frac{\mathbf{r}^{(k+1)} \cdot \mathbf{r}^{(k+1)}}{\mathbf{r}^{(k)} \cdot \mathbf{r}^{(k)}}$ -\State $\mathbf{p}^{(k+1)} \gets \mathbf{r}^{(k+1)} + \beta_k \mathbf{p}^{(k)}$ -\EndWhile -\State $\boldsymbol{\varepsilon}(\mathbf{x}) \gets \bar{\boldsymbol{\varepsilon}} + \tilde{\boldsymbol{\varepsilon}}^{(\text{converged})}(\mathbf{x})$ -\end{algorithmic} -$$ - - -## 4. Known Pitfalls -**Gibbs phenomenon at material interfaces:** The Fourier-Galerkin method evaluates the variational principle on global trigonometric polynomials, which causes high-frequency ringing artifacts (Gibbs phenomenon) near sharp material interfaces and non-smooth boundaries. These oscillations reduce the accuracy of local microscopic fields even though macroscopic effective properties remain accurate. - - -**Failure for porous materials with infinite contrast:** The method fails for materials with infinite phase contrast (e.g., porous foams with voids). Trigonometric polynomials are global functions, so any small numerical error at a solid-pore interface propagates throughout the entire domain. The scheme cannot prescribe the required boundary values at pore surfaces, causing complete solver destabilization. - - -**Expensive Fourier-space constitutive law evaluation:** The Fourier-Galerkin approach must project the local constitutive behavior into Fourier space via spatial convolution of Fourier coefficients, requiring explicit knowledge of the stiffness field's Fourier coefficients. This is computationally expensive and fundamentally limits the method to linear elastic constitutive laws without additional Newton linearization. - - -**Symmetry loss at Nyquist on even grids:** When the grid has an even number of voxels per dimension, the strict symmetries of the projection operator $\hat{\mathbf{G}}^s$ are lost at the Nyquist frequencies. The operator must be explicitly set to zero at these frequencies to recover real-valued fields, introducing an approximation that affects accuracy. - - -**No reference medium required but CG convergence depends on contrast:** While the Galerkin formulation avoids the reference medium $\mathbf{C}^0$ of the basic scheme, the conjugate gradient solver's convergence rate still depends on the condition number of the linear operator $A$, which is governed by the stiffness contrast between phases. High contrast materials require preconditioning for practical efficiency. - - -## 5. References -- Schneider (2021) — Fourier-Galerkin discretization approach for FFT homogenization -- Vondrejc, Zeman, Marek — Galerkin method with trigonometric projection and CG solver -- Brisard, Dormieux — Hashin-Shtrikman variational principles and Galerkin bounds - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-green-operator.md b/packages/akms/src/akms/_bundled/global_nodes/fft-green-operator.md deleted file mode 100644 index cd4d02c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-green-operator.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -id: fft-green-operator -title: Green's Operator (Γ⁰) in Fourier Space -domain: fft-galerkin -subdomain: spectral-operators -tags: -- green-operator -- fft-galerkin -- spectral -- lippmann-schwinger -- homogenization -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Green's operator is the kernel of the Lippmann-Schwinger equation -- to: fft-reference-medium - type: requires - weight: 0.9 - note: Operator depends on the reference medium stiffness C0 -- to: fft-freq-grid - type: requires - weight: 0.8 - note: Operator evaluation requires proper frequency grid with Nyquist treatment -- to: fft-galerkin-basics - type: feeds-into - weight: 0.7 - note: Galerkin discretization modifies the Green's operator -context_size: medium -reading_priority: full -load_with: -- fft-lippmann-schwinger -- fft-freq-grid -content_ref: null -akms_schema: v2 ---- - -# Green's Operator (Γ⁰) in Fourier Space - -## Summary -The Green's operator $\boldsymbol{\Gamma}^0$ (also called the Eshelby-Green operator) maps a stress-type polarization field to a strain fluctuation field in the Lippmann-Schwinger equation. In real space it acts as a singular convolution integral; in Fourier space it reduces to a closed-form algebraic expression involving the frequency vector and reference medium parameters. This Fourier-space form is what makes FFT-based homogenization computationally efficient. Key implementation concerns include the singularity at zero frequency, loss of symmetry at the Nyquist frequency for even grids, and the choice between continuous and discrete operator variants. - - -## 1. Core Concept -The Green's operator $\boldsymbol{\Gamma}^0$ is a fourth-order tensor-valued operator that relates the stress polarization field to the resulting strain fluctuation within a homogeneous reference medium. In real space, it acts via convolution with a singular integral kernel $\mathbf{K}^0$. The key advantage for FFT methods is that in Fourier space, this convolution becomes a pointwise algebraic product with an explicit closed-form formula depending only on the reference medium parameters and the frequency vector. For an isotropic reference medium $\mathbf{C}_0 = 2\mu_0 \mathbf{Id}$, the Fourier-space operator can be written in terms of the re-scaled frequency vector and the shear modulus $\mu_0$. - - -## 2. Mathematical Formulation -The Green's operator has a real-space form as a convolution integral and a Fourier-space form as an algebraic expression. The Fourier-space form is the one used in practice because it avoids evaluating the singular integral directly. The operator vanishes at zero frequency (corresponding to the macroscopic average), and its evaluation at the Nyquist frequency requires special treatment on even grids to preserve symmetry. - - -**Real-space form (convolution integral):** - -$$ -(\boldsymbol{\Gamma}^0 : \boldsymbol{\tau})(\mathbf{x}) = \int_Y \mathbf{K}^0(\mathbf{x} - \mathbf{y}) : \boldsymbol{\tau}(\mathbf{y}) \, d\mathbf{y} -$$ - -where K0 is the singular integral kernel, Y is the periodic cell, x-y is understood Y-periodically - -**Fourier-space form (isotropic reference C0 = 2mu0 Id):** - -$$ -(\hat{\boldsymbol{\Gamma}}^0 : \boldsymbol{\tau})(\boldsymbol{\xi}) = \frac{1}{\mu_0} \left[ \frac{\boldsymbol{\xi}_Y \otimes^s (\hat{\boldsymbol{\tau}}(\boldsymbol{\xi})\boldsymbol{\xi}_Y)}{\|\boldsymbol{\xi}_Y\|^2} - \frac{\boldsymbol{\xi}_Y \cdot (\hat{\boldsymbol{\tau}}(\boldsymbol{\xi})\boldsymbol{\xi}_Y)}{2\|\boldsymbol{\xi}_Y\|^4} \boldsymbol{\xi}_Y \otimes \boldsymbol{\xi}_Y \right] -$$ - -where Valid for xi != 0. xi_Y is the re-scaled frequency vector, mu0 is the reference shear modulus - -**Re-scaled frequency vector:** - -$$ -\boldsymbol{\xi}_Y = \left(\frac{2\pi\xi_1}{L_1}, \frac{2\pi\xi_2}{L_2}, \ldots, \frac{2\pi\xi_d}{L_d}\right) -$$ - -where xi_i are integer frequency indices, L_i are the cell dimensions in each direction - -**Zero-frequency condition:** - -$$ -(\hat{\boldsymbol{\Gamma}}^0 : \boldsymbol{\tau})(\mathbf{0}) = 0 -$$ - -where The operator vanishes at xi=0 — macroscopic strain is prescribed, not computed - -**Notation:** - -- $\boldsymbol{\Gamma}^0$ — Green's operator (Eshelby-Green operator) of the reference medium -- $\hat{\boldsymbol{\Gamma}}^0$ — Green's operator in Fourier space -- $\mathbf{K}^0$ — Singular integral kernel in real space -- $\boldsymbol{\tau}$ — Stress polarization field -- $\boldsymbol{\xi}$ — Integer frequency vector -- $\boldsymbol{\xi}_Y$ — Re-scaled frequency vector accounting for cell dimensions -- $\mu_0$ — Shear modulus of the isotropic reference medium -- $\otimes^s$ — Symmetrized tensor product -- $Y$ — Periodic computational cell with dimensions L1 x L2 x ... x Ld - - -## 3. Algorithmic Implementation -Not applicable — the Green's operator is a mathematical object, not an algorithm. Its evaluation is embedded within the solver iteration loops (see fft-solver-basic-scheme and related nodes). - -## 4. Known Pitfalls -**Singularity at zero frequency:** The Green's operator formula requires dividing by $\|\boldsymbol{\xi}_Y\|^2$, which is undefined at $\boldsymbol{\xi} = \mathbf{0}$. This must be handled explicitly by setting $\hat{\boldsymbol{\Gamma}}^0(\mathbf{0}) = 0$. In displacement-based formulations (DBFFT), the zero-frequency terms must be removed from the linear system entirely. - - -**Symmetry loss at Nyquist frequency:** On grids with even number of discrete frequencies, the tensor symmetries of the Fourier projection operator are lost at the Nyquist frequency. Common fixes: set the operator to zero at Nyquist, or explicitly redefine it to recover symmetry. Failure to handle this produces complex-valued (non-physical) mechanical fields. - - -**Continuous vs discrete operator tradeoffs:** The continuous operator uses exact frequency vectors but suffers from Gibbs phenomena at interfaces and fails for porous materials. Discrete operators (finite difference stencils) replace $\boldsymbol{\xi}$ with modified trigonometric frequency multipliers, which suppress Gibbs but can introduce checkerboarding (Willot's scheme) or oscillations (central differences). Neither choice is universally superior. - - -**Consistent operator pre-computation cost:** Variational approaches (Hashin-Shtrikman by Brisard-Dormieux) require an energetically consistent discrete Green's operator whose Fourier coefficients converge slowly in 3D. This operator cannot be computed on-the-fly and must be pre-computed and stored, adding substantial memory overhead. - - -**Global error propagation in porous media:** The continuous Green's operator with trigonometric polynomial basis attempts elastic extension into void space. Since trigonometric polynomials are global functions, any boundary error at the solid-pore interface propagates throughout the entire domain, producing completely unphysical results. - - -## 5. References -- Schneider (2021) — Fourier-space and real-space Green's operator definitions -- Lucarini et al. (2022) — Green's function in Lippmann-Schwinger context - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-lippmann-schwinger.md b/packages/akms/src/akms/_bundled/global_nodes/fft-lippmann-schwinger.md deleted file mode 100644 index a018a8d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-lippmann-schwinger.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: fft-lippmann-schwinger -title: Lippmann-Schwinger Equation -domain: fft-galerkin -subdomain: spectral-operators -tags: -- lippmann-schwinger -- fft-galerkin -- homogenization -- green-operator -- spectral -- micromechanics -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: homogenization-cell-problem - type: requires - weight: 1.0 - note: L-S equation reformulates the periodic cell problem -- to: fft-green-operator - type: requires - weight: 1.0 - note: L-S equation uses the Green's operator as its kernel -- to: fft-reference-medium - type: requires - weight: 0.9 - note: Polarization field depends on reference medium choice -- to: fft-solver-basic-scheme - type: feeds-into - weight: 1.0 - note: Basic scheme is the fixed-point iteration on L-S equation -- to: fft-galerkin-basics - type: feeds-into - weight: 0.8 - note: Galerkin approach provides alternative derivation -- to: fft-coupled-problems - type: feeds-into - weight: 0.7 - note: Lippmann-Schwinger equation extends to multi-physics coupled problems -context_size: medium -reading_priority: full -load_with: -- fft-green-operator -- fft-reference-medium -content_ref: null -akms_schema: v2 ---- - -# Lippmann-Schwinger Equation - -## Summary -The Lippmann-Schwinger equation is the integral equation reformulation of the periodic cell problem that underpins all FFT-based homogenization methods. It replaces the heterogeneous PDE with an implicit equation involving a stress polarization field convolved with the Green's operator of a homogeneous reference medium. In Fourier space, the convolution becomes a pointwise product, enabling O(N log N) solution via FFT. The equation is the starting point for the basic scheme, polarization methods, and Krylov solvers. Its convergence depends critically on reference medium selection and phase contrast ratio. - - -## 1. Core Concept -The Lippmann-Schwinger equation is derived by replacing the heterogeneous microstructure with a homogeneous linear elastic reference medium characterized by stiffness $\mathbf{C}^0$. The difference between the actual local stiffness and the reference stiffness creates a stress polarization field $\boldsymbol{\tau}$. The local strain fluctuations induced by these heterogeneities are expressed as a convolution of the polarization with the Green's operator $\boldsymbol{\Gamma}^0$ of the reference medium. Because the Green's operator has a closed-form expression in Fourier space, the convolution becomes a simple product, making the equation tractable via FFT. The equation is implicit because the polarization depends on the unknown strain field, requiring iterative solution. - - -## 2. Mathematical Formulation -The strain field is decomposed into a macroscopic average $\bar{\boldsymbol{\varepsilon}}$ and a periodic fluctuation $\tilde{\boldsymbol{\varepsilon}}$ with zero mean. A reference medium with stiffness $\mathbf{C}^0$ is introduced, and the stress polarization $\boldsymbol{\tau} = (\mathbf{C}(\mathbf{x}) - \mathbf{C}^0) \colon \boldsymbol{\varepsilon}(\mathbf{x})$ captures the heterogeneity. The Lippmann-Schwinger equation expresses the strain field as the macroscopic strain minus the convolution of the Green's operator with the polarization. In Fourier space, this convolution becomes a pointwise product, which is the key to FFT efficiency. - - -**Strain decomposition:** - -$$ -\boldsymbol{\varepsilon}(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}} + \tilde{\boldsymbol{\varepsilon}}(\mathbf{x}), \quad \langle \tilde{\boldsymbol{\varepsilon}} \rangle_\Omega = 0 -$$ - -where epsilon-bar is the prescribed macroscopic strain, epsilon-tilde is the zero-mean periodic fluctuation - -**Stress polarization:** - -$$ -\boldsymbol{\tau}(\mathbf{x}) = [\mathbf{C}(\mathbf{x}) - \mathbf{C}^0] : \boldsymbol{\varepsilon}(\mathbf{x}) -$$ - -where C(x) is the local stiffness tensor, C0 is the reference medium stiffness - -**Lippmann-Schwinger equation (real space):** - -$$ -\boldsymbol{\varepsilon}(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}} - (\boldsymbol{\Gamma}^0 * \boldsymbol{\tau})(\mathbf{x}) -$$ - -where Gamma-0 is the Green's operator of the reference medium, * denotes spatial convolution - -**Strain fluctuation form:** - -$$ -\tilde{\boldsymbol{\varepsilon}}(\mathbf{x}) = -(\boldsymbol{\Gamma}^0 * \boldsymbol{\tau}(\tilde{\boldsymbol{\varepsilon}}))(\mathbf{x}) -$$ - -where The fluctuation form emphasizes the implicit nature — tau depends on epsilon-tilde - -**Lippmann-Schwinger equation (Fourier space):** - -$$ -\hat{\boldsymbol{\varepsilon}}(\boldsymbol{\xi}) = \bar{\boldsymbol{\varepsilon}} \delta_{\boldsymbol{\xi},\mathbf{0}} - \hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) : \hat{\boldsymbol{\tau}}(\boldsymbol{\xi}) -$$ - -where xi is the frequency vector, hat denotes Fourier coefficients, delta is the Kronecker delta - -**Notation:** - -- $\boldsymbol{\varepsilon}$ — Local strain tensor -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain -- $\tilde{\boldsymbol{\varepsilon}}$ — Periodic strain fluctuation (zero mean) -- $\boldsymbol{\tau}$ — Stress polarization tensor -- $\mathbf{C}$ — Local fourth-order stiffness tensor -- $\mathbf{C}^0$ — Reference medium stiffness tensor -- $\boldsymbol{\Gamma}^0$ — Green's operator of the reference medium -- $\hat{\boldsymbol{\Gamma}}^0$ — Green's operator in Fourier space -- $\boldsymbol{\xi}$ — Frequency vector in Fourier space - - -## 3. Algorithmic Implementation -Not applicable — the Lippmann-Schwinger equation defines the integral equation formulation. Iterative solution algorithms are covered in the solver nodes (fft-solver-basic-scheme, etc.). - -## 4. Known Pitfalls -**Reference medium sensitivity:** The choice of $\mathbf{C}^0$ dictates convergence. If too soft, the fixed-point iteration diverges (overly large step size). If too stiff, convergence is extremely slow. The optimal choice for the basic scheme is the arithmetic mean of extreme phase stiffnesses; for polarization schemes it is the geometric mean. - - -**Linear scaling with contrast:** For the basic scheme, the number of iterations scales linearly with the phase contrast ratio $\kappa = \alpha_+ / \alpha_-$. For high-contrast composites (e.g., metal matrix with ceramic reinforcement), this makes the basic scheme impractically slow. Krylov and polarization methods improve to $\sqrt{\kappa}$ scaling. - - -**Failure at infinite contrast:** The continuous L-S formulation fails for porous materials (voids) or rigid inclusions. Trigonometric polynomials attempt continuous elastic extension into pore space; since they are global, boundary errors propagate throughout the domain. Average stress may falsely converge to zero in porous foams. - - -**Non-symmetry of the operator:** The continuous Lippmann-Schwinger operator is not symmetric over the general space of square-integrable fields — it is only symmetric and positive definite on the subspace of compatible strain fields. This historically complicated direct application of conjugate gradient solvers. - - -**Gibbs phenomenon at interfaces:** Standard Fourier discretization of the L-S equation produces ringing artifacts near sharp material interfaces due to Fourier series truncation. Alternative finite difference discretizations trade Gibbs for checkerboarding or oscillatory artifacts. - - -## 5. References -- Schneider (2021) — §2.1: Lippmann-Schwinger formulation -- Lucarini et al. (2022) — §3.2: Lippmann-Schwinger approaches for elasticity - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-mixed-bc.md b/packages/akms/src/akms/_bundled/global_nodes/fft-mixed-bc.md deleted file mode 100644 index c0b41af..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-mixed-bc.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -id: fft-mixed-bc -title: Mixed Boundary Conditions & Stress Control -domain: fft-galerkin -subdomain: boundary-conditions -tags: -- boundary-conditions -- stress-control -- mixed-loading -- fft-galerkin -- homogenization -- spectral -- non-periodic -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-periodic-bc - type: requires - weight: 1.0 - note: Mixed BCs extend the standard periodic BC framework with stress/strain component selection -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Mixed control modifies the Lippmann-Schwinger equation with projection operators -- to: fft-reference-medium - type: requires - weight: 0.8 - note: Reference compliance D0 enters the modified L-S equation for mixed loading -- to: fft-solver-basic-scheme - type: feeds-into - weight: 0.8 - note: Modified L-S equation can be solved with any standard FFT solver -- to: fft-dual-scheme - type: requires - weight: 0.7 - note: Stress control is naturally handled in the dual formulation; mixed BCs bridge primal and dual -- to: fft-finite-strain - type: feeds-into - weight: 0.6 - note: Mixed loading is essential for realistic finite-strain simulations (e.g., uniaxial tension) -context_size: medium -reading_priority: full -load_with: -- fft-periodic-bc -- fft-lippmann-schwinger -content_ref: null -akms_schema: v2 ---- - -# Mixed Boundary Conditions & Stress Control - -## Summary -Standard FFT-based homogenization prescribes a fully determined macroscopic strain tensor, but many practical simulations require controlling macroscopic stress components (e.g., zero lateral stress in uniaxial tension) or imposing non-periodic boundary conditions. Mixed boundary conditions are formulated using orthogonal complementary projection operators P and Q that partition the macroscopic loading into strain-controlled and stress-controlled components. This leads to a modified Lippmann-Schwinger equation incorporating the reference compliance and a volume-averaging stress projection term. For non-periodic problems, the Fourier Continuation (FC) method constructs smooth periodic extensions via artificial boundary points, while Bloch boundary conditions handle long-wavelength periodic fluctuations across multiple unit cells. - - -## 1. Core Concept -The classical Lippmann-Schwinger equation is driven by a fully prescribed macroscopic strain $\bar{\boldsymbol{\varepsilon}}$, but real experiments often require mixed control: some macroscopic strain components are prescribed while complementary macroscopic stress components are constrained. The mixed formulation introduces two orthogonal complementary projection operators $\mathbb{P}$ and $\mathbb{Q} = \mathbf{Id} - \mathbb{P}$ acting on symmetric tensors $\text{Sym}(d)$. Operator $\mathbb{P}$ selects the strain-controlled components ($\mathbb{P} \colon \bar{\boldsymbol{\varepsilon}} = \bar{\boldsymbol{\varepsilon}}$) and $\mathbb{Q}$ selects the stress-controlled components ($\mathbb{Q} \colon \bar{\boldsymbol{\sigma}} = \bar{\boldsymbol{\sigma}}$). The cell problem under mixed control simultaneously enforces equilibrium, the prescribed strain components via $\mathbb{P}$, and the prescribed stress components via $\mathbb{Q}$ applied to the volume-averaged stress. The resulting modified Lippmann-Schwinger equation augments the standard Green operator with a compliance-weighted stress projection term, enabling any existing FFT solver to handle mixed loading without fundamental algorithmic changes. An older, less efficient approach iteratively corrected the fully prescribed macroscopic strain at each step based on the residual of the target macroscopic stress. - - -## 2. Mathematical Formulation -The mixed equilibrium problem seeks a macroscopic strain variable $\mathbf{E}$ and displacement fluctuation $\mathbf{u}$ satisfying equilibrium, the strain-controlled constraint via projector $\mathbb{P}$, and the stress-controlled constraint via projector $\mathbb{Q}$ applied to the volume-averaged stress. The system is reformulated into a modified Lippmann-Schwinger equation by incorporating the reference compliance and the stress projection into the operator. - - -**Mixed equilibrium problem — divergence condition:** - -$$ -\text{div}\, \frac{\partial w}{\partial \boldsymbol{\varepsilon}}(\cdot, \mathbf{E} + \nabla^s \mathbf{u}) = 0 -$$ - -where w is the free energy density, E is the macroscopic strain variable, u is the displacement fluctuation - -**Strain-controlled components:** - -$$ -\mathbb{P} \colon \mathbf{E} = \bar{\boldsymbol{\varepsilon}} -$$ - -where P is the projection operator selecting strain-controlled components, epsilon-bar is the prescribed macroscopic strain - -**Stress-controlled components (volume-averaged):** - -$$ -\mathbb{Q} \colon \frac{1}{\text{vol}(Y)} \int_Y \frac{\partial w}{\partial \boldsymbol{\varepsilon}}(\mathbf{x}, \mathbf{E} + \nabla^s \mathbf{u})\, d\mathbf{x} = \bar{\boldsymbol{\sigma}} -$$ - -where Q = Id - P is the complementary projector selecting stress-controlled components, sigma-bar is the prescribed macroscopic stress - -**Modified Lippmann-Schwinger equation for mixed loading:** - -$$ -\boldsymbol{\varepsilon} + \left(\boldsymbol{\Gamma}^0 + \mathbf{D}^0 \colon \mathbb{Q} \colon \frac{1}{\text{vol}(Y)} \int_Y \cdot\, d\mathbf{x}\right) \colon \left(\frac{\partial w}{\partial \boldsymbol{\varepsilon}}(\cdot, \boldsymbol{\varepsilon}) - \mathbf{C}^0 \colon \boldsymbol{\varepsilon}\right) = \bar{\boldsymbol{\varepsilon}} + \mathbf{D}^0 \colon \bar{\boldsymbol{\sigma}} -$$ - -where Gamma0 is the Green operator, D0 = (1/alpha_0) Id is the reference compliance, C0 = alpha_0 Id is the reference stiffness - -**Orthogonal projector admissibility:** - -$$ -\mathbb{P} + \mathbb{Q} = \mathbf{Id}, \quad \mathbb{P} \colon \mathbb{Q} = \mathbf{0} -$$ - -where P and Q are complementary orthogonal projectors on Sym(d); pure strain control sets Q=0, pure stress control sets P=0 - -**Notation:** - -- $\mathbb{P}$ — Projection operator selecting strain-controlled macroscopic components -- $\mathbb{Q}$ — Complementary projection operator selecting stress-controlled macroscopic components -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain (strain-controlled components) -- $\bar{\boldsymbol{\sigma}}$ — Prescribed macroscopic stress (stress-controlled components) -- $\mathbf{E}$ — Macroscopic strain variable (unknown for stress-controlled components) -- $\mathbf{D}^0$ — Reference compliance tensor, D0 = (C0)^{-1} -- $\boldsymbol{\Gamma}^0$ — Green operator of the reference medium -- $w$ — Local condensed free energy density - - -## 3. Algorithmic Implementation -Not applicable — this is a concept node describing the mathematical formulation of mixed boundary conditions. The modified Lippmann-Schwinger equation is solved using standard FFT solvers (basic scheme, Krylov, Newton) with the augmented operator replacing the standard Green operator. - -## 4. Known Pitfalls -**Projector construction for non-standard loading:** The orthogonal projectors $\mathbb{P}$ and $\mathbb{Q}$ must be constructed carefully for each loading scenario. For standard cases (uniaxial tension, biaxial loading), the projectors select individual tensor components, but for more complex loading paths (e.g., proportional loading in a rotated frame), constructing the correct projectors requires care to maintain orthogonality and admissibility conditions. - - -**Non-periodic problems require specialized extensions:** The FFT framework strictly requires periodicity. Non-periodic problems (finite-sized components, traction-free surfaces, wave scattering) require the Fourier Continuation (FC) method, which appends artificial points at boundaries to construct smooth periodic extensions, or Bloch boundary conditions for long-wavelength fluctuations. Both add significant implementation complexity and computational cost. - - -**Iterative strain correction (legacy approach) is inefficient:** An older approach to stress control iteratively corrected the fully prescribed macroscopic strain at each solver step based on the residual between computed and target macroscopic stress. This nested iteration is significantly less efficient than the projector-based modified Lippmann-Schwinger approach, which handles mixed loading within a single unified iteration. - - -**Convergence may differ from pure strain control:** The modified Lippmann-Schwinger operator includes additional terms (compliance-weighted stress projection) that change the spectral properties of the iteration operator. Convergence behavior may differ from the standard strain-controlled case, particularly near material instabilities or for nearly incompressible materials where the compliance tensor becomes ill-conditioned. - - -## 5. References -- Schneider (2021) — Review of nonlinear FFT-based computational homogenization, mixed boundary conditions formulation -- Kabel, Fliegener, Schneider (2016) — Mixed boundary conditions for FFT-based homogenization at finite strains -- Lucarini, Segurado (2019) — FFT-based approach with mixed stress-strain control - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-periodic-bc.md b/packages/akms/src/akms/_bundled/global_nodes/fft-periodic-bc.md deleted file mode 100644 index 24c68c0..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-periodic-bc.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: fft-periodic-bc -title: Periodic Boundary Conditions for FFT -domain: fft-galerkin -subdomain: boundary-conditions -tags: -- periodic-bc -- boundary-conditions -- fft-galerkin -- homogenization -- spectral -- micromechanics -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: homogenization-cell-problem - type: requires - weight: 1.0 - note: Periodic BCs are the defining boundary conditions for the homogenization cell problem -- to: fft-lippmann-schwinger - type: feeds-into - weight: 1.0 - note: Periodicity enables reformulation as Lippmann-Schwinger integral equation solvable via FFT -- to: fft-galerkin-basics - type: feeds-into - weight: 0.9 - note: Periodic fields are represented as Fourier series in the Galerkin discretization -- to: fft-freq-grid - type: feeds-into - weight: 0.8 - note: Periodicity of the domain maps directly to the discrete frequency grid -- to: fft-mixed-bc - type: feeds-into - weight: 0.8 - note: Mixed and non-periodic BCs are extensions beyond the standard periodic assumption -context_size: medium -reading_priority: full -load_with: -- homogenization-cell-problem -- fft-lippmann-schwinger -content_ref: null -akms_schema: v2 ---- - -# Periodic Boundary Conditions for FFT - -## Summary -Periodic boundary conditions are the foundational assumption enabling FFT-based computational homogenization. The representative volume element (RVE) is treated as a periodic cell, requiring that the microscopic strain field is periodic across opposite faces, the traction vector is anti-periodic (ensuring equilibrium between adjacent cells), and the volume average of the local strain equals the prescribed macroscopic strain. This periodicity naturally aligns with the discrete Fourier transform: local fields decompose into Fourier series, and differential operators become algebraic multiplications in frequency space, yielding O(N log N) computational cost. Empirically, periodic BCs produce homogenized results with smaller bias than Dirichlet or Neumann conditions. - - -## 1. Core Concept -In FFT-based computational homogenization, the rectangular domain $\Omega$ representing the microstructure is assumed to tile space periodically. This periodic cell assumption has three consequences: (1) it enables representation of all fields as Fourier series, converting spatial convolutions into frequency-space products for efficient O(N log N) evaluation; (2) it allows the Lippmann-Schwinger integral equation reformulation that underpins all FFT solvers; and (3) it produces the smallest statistical bias in effective properties compared to Dirichlet or Neumann boundary conditions for finite-size RVEs. The local strain field is decomposed as $\boldsymbol{\varepsilon}(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}} + \tilde{\boldsymbol{\varepsilon}}(\mathbf{x})$, where $\bar{\boldsymbol{\varepsilon}}$ is the prescribed macroscopic strain and $\tilde{\boldsymbol{\varepsilon}}$ is the periodic fluctuation with zero spatial average. For finite strain formulations in a total Lagrangian framework, the periodicity condition applies to the deformation gradient field $\mathbf{F}(\mathbf{X})$ and anti-periodicity to the first Piola-Kirchhoff stress traction $\tilde{\mathbf{P}}(\mathbf{X}) \cdot \mathbf{N}$. - - -## 2. Mathematical Formulation -The periodic cell problem seeks local strain $\boldsymbol{\varepsilon}(\mathbf{x})$ and stress $\boldsymbol{\sigma}(\mathbf{x})$ fields satisfying equilibrium, compatibility, the constitutive law, and three boundary constraints that enforce periodicity, anti-periodicity of tractions, and volume averaging. - - -**Volume averaging constraint:** - -$$ -\langle \boldsymbol{\varepsilon}(\mathbf{x}) \rangle_\Omega = \bar{\boldsymbol{\varepsilon}} -$$ - -where angle brackets denote spatial average over the periodic domain Omega, epsilon-bar is the prescribed macroscopic strain - -**Strain decomposition into mean and fluctuation:** - -$$ -\boldsymbol{\varepsilon}(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}} + \tilde{\boldsymbol{\varepsilon}}(\mathbf{x}), \quad \langle \tilde{\boldsymbol{\varepsilon}}(\mathbf{x}) \rangle_\Omega = 0 -$$ - -where epsilon-tilde is the periodic strain fluctuation with zero spatial average - -**Periodicity of strain:** - -$$ -\boldsymbol{\varepsilon}(\mathbf{x}) \quad \text{periodic on } \partial\Omega -$$ - -where strain values on opposite faces of the RVE are identical - -**Anti-periodicity of traction:** - -$$ -\boldsymbol{\sigma}(\mathbf{x}) \cdot \mathbf{n}(\mathbf{x}) \quad \text{anti-periodic on } \partial\Omega -$$ - -where n(x) is the outward unit normal; traction is equal and opposite on opposing faces, ensuring equilibrium between adjacent cells - -**Equilibrium (divergence-free stress):** - -$$ -\nabla \cdot \boldsymbol{\sigma}(\mathbf{x}) = 0 \quad \text{in } \Omega -$$ - -where Cauchy stress satisfies balance of linear momentum with zero body forces - -**Finite strain periodicity (total Lagrangian):** - -$$ -\mathbf{F}(\mathbf{X}) \text{ periodic}, \quad \tilde{\mathbf{P}}(\mathbf{X}) \cdot \mathbf{N} \text{ anti-periodic} -$$ - -where F is the deformation gradient, P-tilde is the first Piola-Kirchhoff stress fluctuation, N is the reference normal - -**Notation:** - -- $\boldsymbol{\varepsilon}$ — Infinitesimal strain tensor -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain -- $\tilde{\boldsymbol{\varepsilon}}$ — Periodic strain fluctuation (zero mean) -- $\boldsymbol{\sigma}$ — Cauchy stress tensor -- $\mathbf{n}$ — Outward unit normal on domain boundary -- $\Omega$ — Periodic computational domain (RVE) -- $\mathbf{F}$ — Deformation gradient tensor (finite strain) -- $\mathbf{P}$ — First Piola-Kirchhoff stress tensor - - -## 3. Algorithmic Implementation -Not applicable — this is a foundational concept node defining the periodic boundary conditions and their mathematical structure, not an algorithmic procedure. - -## 4. Known Pitfalls -**Gibbs phenomenon at material interfaces:** Global trigonometric polynomials used by FFT cannot accurately represent the discontinuous fields at sharp material interfaces, producing spurious high-frequency oscillations (ringing artifacts). This is especially severe for high-contrast materials and higher-order spatial derivatives (e.g., strain gradient plasticity). Discrete finite-difference differentiation rules (central differences, rotated staggered grids) can mitigate these artifacts. - - -**Inapplicability to non-periodic microstructures:** Standard FFT algorithms strictly require periodic domains and cannot naturally handle finite-sized geometries or general non-periodic boundary conditions such as traction-free surfaces. Workarounds include the Fourier Continuation (FC) method, which constructs smooth periodic extensions by appending artificial points at domain boundaries, and Bloch boundary conditions for problems with long-wavelength periodic fluctuations across multiple unit cells. - - -**Failure for infinite contrast (porous/rigid):** The basic continuous FFT scheme requires a continuous elastic extension into void or rigid regions via global trigonometric polynomials. Because these polynomials cannot prescribe exact boundary values at solid-pore interfaces, small numerical errors propagate globally, causing the average stress to falsely converge to zero. Finite-difference discretizations (e.g., Willot's rotated staggered grid) can resolve pore boundaries but may introduce hourglass instabilities. - - -**Statistical bias from insufficient RVE size:** Even with periodic BCs producing less bias than Dirichlet or Neumann conditions, the RVE must be sufficiently large relative to the microstructural correlation length. Undersized RVEs yield unreliable effective properties dominated by statistical randomness. There is no universal formula for minimum RVE size — it depends on contrast ratio, volume fraction, and the property of interest. - - -## 5. References -- Schneider (2021) — Review of nonlinear FFT-based computational homogenization, periodic boundary conditions and cell problem formulation -- Lucarini et al. (2022) — FFT-based approaches review, periodic BCs and finite strain extensions - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-phase-field.md b/packages/akms/src/akms/_bundled/global_nodes/fft-phase-field.md deleted file mode 100644 index 80cbf1d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-phase-field.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: fft-phase-field -title: Phase-Field Fracture with FFT -domain: fft-galerkin -subdomain: coupled-problems -tags: -- fft-galerkin -- phase-field -- fracture -- damage -- homogenization -- spectral -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Mechanical sub-problem solved via Lippmann-Schwinger with degraded stiffness -- to: fft-green-operator - type: requires - weight: 0.9 - note: Green's operator applied in the mechanical sub-step of the staggered scheme -- to: fft-solver-basic-scheme - type: requires - weight: 0.7 - note: Basic scheme or fast gradient method used as inner solver for mechanical sub-problem -- to: pf-at2-regularization - type: requires - weight: 0.9 - note: Phase-field fracture model provides the degradation function and evolution equation -- to: fft-galerkin-basics - type: requires - weight: 0.8 - note: FFT framework provides the spectral solver infrastructure -- to: fft-convergence-schemes - type: feeds-into - weight: 0.5 - note: Accelerated schemes can be used within the mechanical sub-step -context_size: large -reading_priority: full -load_with: -- fft-lippmann-schwinger -- pf-at2-regularization -content_ref: null -akms_schema: v2 ---- - -# Phase-Field Fracture with FFT - -## Summary -Phase-field fracture with FFT solves brittle fracture by smoothing the discrete crack into a continuous damage field $\phi$ concentrated in a thin volume of width $\ell$, where the sharp crack topology is recovered as $\ell \to 0$. The coupled system consists of mechanical equilibrium $\nabla \cdot \boldsymbol{\sigma}(\mathbf{u}, \phi) = 0$ with degraded stiffness $g(\phi) = (1-\phi)^2 + k$, and a phase-field evolution equation $g'(\phi) U_0(\boldsymbol{\varepsilon}) + R(\frac{1}{\ell}\phi - \ell \nabla^2 \phi) = 0$. FFT methods are ideal because the crack path is tracked by $\phi$ on a regular voxel grid without remeshing. A staggered algorithm alternately solves the mechanical sub-problem (via Lippmann-Schwinger with degraded stiffness) and the phase-field sub-problem (a linear Helmholtz-type equation). Discrete Green's operators must replace continuous ones to suppress Gibbs oscillations near the crack interface. - - -## 1. Core Concept -Phase-field fracture models represent cracks as a continuous damage field $\phi$ that transitions smoothly from intact ($\phi = 0$) to fully broken ($\phi = 1$) over a regularization length $\ell$. The degradation function $g(\phi) = (1-\phi)^2 + k$ couples the damage to the mechanical stiffness, and the phase-field evolution is driven by the elastic strain energy density $U_0$. FFT-based solvers operating on regular voxel grids provide an ideal framework because they avoid the remeshing required by FEM to track evolving crack paths. The coupled system is universally solved by staggered integration that alternately solves the mechanical and phase-field sub-problems, providing robust control over crack propagation. Discrete derivatives and discrete Green's operators are essential to suppress Gibbs oscillations at the sharp damage interfaces. - - -## 2. Mathematical Formulation -The variational phase-field model balances elastic energy storage (degraded by the damage field) against crack surface energy. The strong form yields two coupled PDEs: mechanical equilibrium with degraded stress, and a reaction-diffusion equation for the phase field. The degradation function $g(\phi)$ couples the two fields. By substituting $g'(\phi) = -2(1-\phi)$, the phase-field equation becomes a linear Helmholtz-type equation that is straightforward to solve in Fourier space. - - -**Mechanical equilibrium with degraded stiffness:** - -$$ -\nabla \cdot \boldsymbol{\sigma}(\mathbf{u}, \phi) = 0, \quad \boldsymbol{\sigma} = g(\phi)\,\mathbf{C} : \boldsymbol{\varepsilon}(\mathbf{u}) -$$ - -where sigma is the degraded Cauchy stress, C is the intact elastic stiffness, epsilon is the strain, g(phi) is the degradation function - -**Phase-field evolution equation:** - -$$ -g'(\phi)\,U_0(\boldsymbol{\varepsilon}(\mathbf{u})) + R\left(\frac{1}{\ell}\phi - \ell\,\nabla^2 \phi\right) = 0 -$$ - -where U_0 is the elastic strain energy density of intact material, R is the fracture toughness, ell is the regularization length scale - -**Degradation function:** - -$$ -g(\phi) = (1 - \phi)^2 + k -$$ - -where k is a small positive residual stiffness parameter to prevent ill-conditioning when phi = 1 - -**Linearized phase-field equation (Helmholtz form):** - -$$ -\left(2U_0 + \frac{R}{\ell}\right)\phi - R\ell\,\nabla^2\phi = 2U_0 -$$ - -where Obtained by substituting g'(phi) = -2(1 - phi) and rearranging; linear in phi for fixed epsilon - -**Weak form of the coupled energy functional:** - -$$ -\int_{\partial\Omega_F} \mathbf{t} \cdot \dot{\mathbf{u}}\,dA = \int_\Omega \left[g'(\phi)\,U_0\,\dot{\phi} + R\left(\frac{1}{\ell}\phi\dot{\phi} + \ell\,\nabla\phi \cdot \nabla\dot{\phi}\right)\right]d\Omega - \int_\Omega \nabla \cdot \boldsymbol{\sigma} \cdot \dot{\mathbf{u}}\,d\Omega -$$ - -where t is the boundary traction on the loaded boundary partial Omega_F - -**Lippmann-Schwinger equation for the mechanical sub-problem:** - -$$ -\hat{\boldsymbol{\varepsilon}}(\boldsymbol{\xi}) = \bar{\boldsymbol{\varepsilon}} - \hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) : \hat{\boldsymbol{\tau}}(\boldsymbol{\xi}), \quad \boldsymbol{\tau}(\mathbf{x}) = g(\phi)\,\mathbf{C} : \boldsymbol{\varepsilon} - \mathbf{C}^0 : \boldsymbol{\varepsilon} -$$ - -where Gamma^0 is the Green's operator, tau is the stress polarization with degraded stiffness, C^0 is the reference medium - -**Notation:** - -- $\phi$ — Phase-field damage variable (0 = intact, 1 = fully broken) -- $g(\phi)$ — Degradation function coupling damage to stiffness -- $U_0$ — Elastic strain energy density of intact material -- $R$ — Fracture toughness (critical energy for unit crack surface) -- $\ell$ — Regularization length scale controlling diffuse crack width -- $k$ — Small residual stiffness parameter for numerical stability -- $\hat{\boldsymbol{\Gamma}}^0$ — Green's operator of the reference medium - - -## 3. Algorithmic Implementation -**Algorithm: Staggered Algorithm for Phase-Field Fracture with FFT** - -$$ -\begin{algorithmic} -\State $Initialize \colon \phi_0(\mathbf{x}) = 0, \; \boldsymbol{\varepsilon}_0(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}}$ -\For{$\text{each load step } n = 1, 2, \ldots$} - \While{$\text{staggered iteration not converged}$} - \State $\text{Step 1 (Mechanical)} \colon \boldsymbol{\sigma}(\mathbf{x}) = g(\phi)\,\mathbf{C} \colon \boldsymbol{\varepsilon}(\mathbf{x})$ - \State $\hat{\boldsymbol{\tau}}(\boldsymbol{\xi}) = \mathcal{F}\{g(\phi)\,\mathbf{C} \colon \boldsymbol{\varepsilon} - \mathbf{C}^0 \colon \boldsymbol{\varepsilon}\}$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\boldsymbol{\xi}) = \bar{\boldsymbol{\varepsilon}} - \hat{\boldsymbol{\Gamma}}^0_{\mathrm{discrete}}(\boldsymbol{\xi}) \colon \hat{\boldsymbol{\tau}}_k(\boldsymbol{\xi})$ - \State $\text{Iterate mechanical solver until } \|\nabla \cdot \boldsymbol{\sigma}\| < \mathrm{tol}_{\mathrm{mech}}$ - \State $\text{Step 2 (Phase-field)} \colon \left(2U_0(\boldsymbol{\varepsilon}) + \frac{R}{\ell}\right)\phi - R\ell\,\nabla^2\phi = 2U_0(\boldsymbol{\varepsilon})$ - \State $\hat{\phi}(\boldsymbol{\xi}) = \frac{2\hat{U}_0(\boldsymbol{\xi})}{2U_0 + R/\ell + R\ell\,|\boldsymbol{\xi}|^2}$ - \EndWhile -\EndFor -\end{algorithmic} -$$ - -**Taichi Mapping:** -Both sub-problems are embarrassingly parallel at the voxel level. The mechanical solver uses standard FFT infrastructure. The phase-field Helmholtz solve is a single-pass pointwise division in Fourier space after FFT of U_0. Discrete derivative operators implemented as modified Fourier multipliers (e.g., Willot rotated staggered grid). The damage field phi stored as a scalar ti.field. - - -## 4. Known Pitfalls -**Gibbs oscillations near crack interfaces:** Phase-field fracture involves sharp transitions in the damage field at the crack boundary. Standard continuous Fourier derivatives produce severe ringing artifacts (Gibbs phenomenon) near these interfaces. Discrete derivatives and discrete Green's operators (e.g., Willot rotated staggered grid or high-order finite differences) must replace continuous ones to maintain stability and accuracy. - - -**Artificial residual stiffness parameter k:** The degradation function $g(\phi) = (1-\phi)^2 + k$ includes a small positive parameter $k$ to prevent the stiffness matrix from becoming singular when $\phi = 1$. This artificially maintains residual load-bearing capacity in fully damaged regions. The value of $k$ must be small enough not to affect the physics but large enough for numerical stability. - - -**Length scale ell sensitivity:** The regularization length $\ell$ controls the width of the diffuse crack zone. The sharp crack limit is only recovered as $\ell \to 0$, so results are inherently sensitive to $\ell$. The voxel grid must be fine enough to resolve the damage band (typically several voxels across $\ell$), creating a coupling between mesh resolution and physical accuracy. - - -**No irreversibility in basic formulation:** The standard variational equations as presented do not include a history variable to enforce damage irreversibility (preventing crack healing upon unloading). Without this constraint, the formulation is strictly valid only for monotonic loading. A strain-energy history field $\mathcal{H}(\mathbf{x}, t) = \max_{\tau \leq t} U_0(\boldsymbol{\varepsilon}(\mathbf{x}, \tau))$ must be added for cyclic or non-monotonic loading. - - -**Operator splitting errors in staggered scheme:** The staggered algorithm decouples the mechanical and phase-field sub-problems, solving them sequentially. This operator splitting introduces temporal integration errors that can reduce accuracy in strongly coupled regimes. Sufficient staggered iterations per load step are needed to ensure convergence of the coupled system. - - -## 5. References -- Schneider (2021) -- Phase-field fracture with FFT, staggered algorithms, discrete operators -- Chen et al. -- Variational phase-field fracture model, degradation function, energy functional -- Willot (2015) -- Discrete Green's operators for suppressing Gibbs oscillations - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-polycrystal.md b/packages/akms/src/akms/_bundled/global_nodes/fft-polycrystal.md deleted file mode 100644 index 754fab9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-polycrystal.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -id: fft-polycrystal -title: FFT for Polycrystalline Materials -domain: fft-galerkin -subdomain: coupled-problems -tags: -- fft-galerkin -- crystal-plasticity -- polycrystal -- homogenization -- spectral -- plasticity -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Mechanical equilibrium solved via Lippmann-Schwinger with anisotropic crystal stiffness -- to: fft-green-operator - type: requires - weight: 0.9 - note: Green's operator used in the iterative solver for polycrystal equilibrium -- to: fft-reference-medium - type: requires - weight: 0.7 - note: Reference medium choice affects convergence; contrast is limited to single-crystal anisotropy -- to: plasticity-general-return-mapping - type: requires - weight: 0.5 - note: Implicit return mapping is an alternative to the explicit Euler integration described inline; see this node for implicit - algorithms -- to: fft-solver-basic-scheme - type: feeds-into - weight: 0.5 - note: Basic scheme is feasible for polycrystals due to low anisotropy contrast -- to: fft-solver-newton-krylov - type: feeds-into - weight: 0.8 - note: Newton-type solvers preferred to minimize expensive crystal plasticity evaluations -- to: fft-finite-strain - type: feeds-into - weight: 0.8 - note: Finite-strain polycrystal simulations use the total Lagrangian framework with F and P -- to: kinematics-multiplicative-decomp - type: requires - weight: 0.5 - note: Multiplicative decomposition F=FeFp is included inline; this edge is for detailed kinematics theory -context_size: large -reading_priority: full -load_with: -- fft-lippmann-schwinger -content_ref: null -akms_schema: v2 ---- - -# FFT for Polycrystalline Materials - -## Summary -FFT homogenization of polycrystalline materials computes the local and macroscopic mechanical response of a polycrystalline aggregate where all grains are the same material differing only in crystallographic orientation. The material contrast is limited to the single-crystal anisotropy, making the basic scheme feasible without severe ill-conditioning. The viscoplastic flow rule $\dot{\boldsymbol{\varepsilon}}^p = \sum_s \mathrm{sym}(\mathbf{m}^s) \dot{\gamma}^s_0 (\mathbf{m}^s : \boldsymbol{\sigma}' / \tau^s_c)^n$ governs plastic deformation on each slip system, with the Schmid tensor $\mathbf{m}^s(\mathbf{x})$ rotated by the local grain orientation. The EVP-FFT framework extends this to include elastic strains via $\boldsymbol{\sigma} = \mathbf{C}(\mathbf{x}) : (\boldsymbol{\varepsilon} - \boldsymbol{\varepsilon}^p)$. Quasi-Newton solvers are strongly preferred because crystal plasticity constitutive evaluation is the computational bottleneck. FFT polycrystal models naturally capture intragranular heterogeneity, strain localization, and texture evolution, and accept EBSD microstructural images directly without meshing. - - -## 1. Core Concept -In FFT polycrystal simulations, the representative volume element is composed of multiple grains of the same material, where the spatially varying crystallographic orientation defines the local elastic stiffness tensor $\mathbf{C}(\mathbf{x})$ and the Schmid tensors $\mathbf{m}^s(\mathbf{x})$ for each slip system. The orientation field enters the constitutive law by rotating the slip systems into the global frame, setting the resolved shear stress that drives plastic flow, and by rotating the anisotropic elastic stiffness. Two main model classes exist: VP-FFT (viscoplastic only, no elastic strains) and EVP-FFT (elasto-viscoplastic, including elastic strains). The phase contrast in polycrystals is restricted to the inner anisotropy of the single crystal, which is relatively low compared to composite materials. This allows the basic scheme to work, but the extreme computational cost of crystal plasticity constitutive evaluations makes quasi-Newton or Newton-type solvers strongly preferred to minimize the number of evaluations. A key advantage over mean-field models (VPSC) is the ability to capture intragranular heterogeneity, grain neighborhood interactions, and complex strain localization patterns. - - -## 2. Mathematical Formulation -The polycrystal FFT framework combines the standard Lippmann-Schwinger mechanical equilibrium with crystal plasticity constitutive laws evaluated at each voxel. The orientation field rotates both the elastic stiffness and the slip system Schmid tensors from the crystal reference frame into the sample frame. The viscoplastic flow rule sums shear contributions from all active slip systems governed by a power-law relation. Hardening is tracked through evolution of the critical resolved shear stress, either phenomenologically or through physically-based dislocation density models. - - -**Resolved shear stress:** - -$$ -\tau^s(\mathbf{x}) = \mathbf{m}^s(\mathbf{x}) : \boldsymbol{\sigma}'(\mathbf{x}) -$$ - -where tau^s is the resolved shear stress on slip system s, m^s is the Schmid tensor, sigma' is the deviatoric Cauchy stress - -**Viscoplastic flow rule (VP-FFT):** - -$$ -\dot{\boldsymbol{\varepsilon}}^p(\mathbf{x}) = \sum_s \mathrm{sym}(\mathbf{m}^s(\mathbf{x}))\,\dot{\gamma}^s_0 \left(\frac{\mathbf{m}^s(\mathbf{x}) : \boldsymbol{\sigma}'(\mathbf{x})}{\tau^s_c(\mathbf{x})}\right)^n -$$ - -where m^s is the Schmid tensor for slip system s, gamma_0_dot_s is the reference shear rate, sigma' is deviatoric stress, tau_c^s is critical resolved shear stress, n is the power-law exponent (inverse rate sensitivity) - -**Elasto-viscoplastic constitutive law (EVP-FFT):** - -$$ -\boldsymbol{\sigma}(\mathbf{x}) = \mathbf{C}(\mathbf{x}) : (\boldsymbol{\varepsilon}(\mathbf{x}) - \boldsymbol{\varepsilon}^p(\mathbf{x})) -$$ - -where C(x) is the local anisotropic elastic stiffness rotated by grain orientation, epsilon is total strain, epsilon^p is plastic strain - -**Schmid tensor from orientation:** - -$$ -\mathbf{m}^s(\mathbf{x}) = \mathbf{R}^*(\mathbf{x})\,\mathbf{m}^s_0\,\mathbf{R}^{*T}(\mathbf{x}), \quad \mathbf{m}^s_0 = \mathbf{d}^s_0 \otimes \mathbf{n}^s_0 -$$ - -where R* is the lattice rotation matrix, m^s_0 is the Schmid tensor in the crystal frame, d^s_0 is the slip direction, n^s_0 is the slip plane normal - -**Stiffness tensor rotation (crystal to sample frame):** - -$$ -C_{ijkl}^{\mathrm{sample}}(\mathbf{x}) = R^*_{im}(\mathbf{x})\, R^*_{jn}(\mathbf{x})\, R^*_{ko}(\mathbf{x})\, R^*_{lp}(\mathbf{x})\, C_{mnop}^{\mathrm{crystal}} -$$ - -where R*_{ij} are the components of the lattice rotation matrix, C^crystal is the single-crystal stiffness in the crystal frame. The compact notation R* star C_crystal star R*^T denotes this four-index Rayleigh product. In Voigt notation this becomes [C^sample] = [M] [C^crystal] [M]^T where [M] is the 6x6 Bond transformation matrix constructed from R*. - -**Phenomenological hardening (Voce-type):** - -$$ -\dot{\tau}^s_c = \sum_{s'} h^{ss'} |\dot{\gamma}^{s'}|, \quad h^{ss'} = q^{ss'}\left[h_0\left(1 - \frac{\tau^s_c}{\tau_{\mathrm{sat}}}\right)^a\right] -$$ - -where h^{ss'} is the hardening moduli matrix, q^{ss'} is the latent hardening ratio (1 for coplanar, q for non-coplanar systems), h_0 is initial hardening rate, tau_sat is saturation stress, a is hardening exponent - -**Dislocation density hardening law:** - -$$ -\tau^s_c = \mu\,b^s \sqrt{\sum_{s'} h^{ss'}\,\rho^{s'}} -$$ - -where mu is shear modulus, b^s is Burgers vector magnitude, h^{ss'} is slip system interaction matrix, rho^{s'} is total dislocation density on system s' - -**SSD dislocation density evolution:** - -$$ -\dot{\rho}^s_{\mathrm{SSD}} = \frac{1}{b^s}\left(\frac{1}{l^s} - 2y_c\,\rho^s_{\mathrm{SSD}}\right)|\dot{\gamma}^s|, \quad l^s = \frac{K}{\sqrt{\sum_{s' \neq s}(\rho^{s'}_{\mathrm{SSD}} + \rho^{s'}_{\mathrm{GND}})}} -$$ - -where rho_SSD is statistically stored dislocation density, y_c is annihilation distance, l^s is mean free path, K is material constant - -**GND dislocation density (from curl of plastic strain):** - -$$ -\boldsymbol{\alpha} = -\nabla \times \boldsymbol{\varepsilon}^p, \quad \bar{\rho}_{\mathrm{GND}} = (\mathbf{A}^T\mathbf{A})^{-1}\mathbf{A}^T\bar{\boldsymbol{\alpha}} -$$ - -where alpha is the polar dislocation density tensor computed in Fourier space, A is the projection matrix for GND density via L2 minimization - -**Finite-strain multiplicative decomposition:** - -$$ -\mathbf{F} = \mathbf{F}_e\,\mathbf{F}_p, \quad \dot{\mathbf{F}}_p = \mathbf{L}_p\,\mathbf{F}_p, \quad \mathbf{L}_p = \sum_s \dot{\gamma}^s\,\mathbf{m}^s_0 -$$ - -where F is total deformation gradient, F_e is elastic part, F_p is plastic part, L_p is plastic velocity gradient - -**Texture update (lattice rotation):** - -$$ -\mathbf{W}_e = \mathbf{W} - \mathbf{W}_p, \quad \mathbf{W}_p = \sum_s \dot{\gamma}^s\,\mathrm{skew}(\mathbf{m}^s_0), \quad \dot{\mathbf{R}}^* = \mathbf{W}_e\,\mathbf{R}^* -$$ - -where W is total continuum spin, W_p is plastic spin, W_e is elastic (lattice) spin, R* is lattice rotation - -**Notation:** - -- $\mathbf{m}^s$ — Schmid tensor for slip system s -- $\dot{\gamma}^s_0$ — Reference shear rate -- $\tau^s_c$ — Critical resolved shear stress for slip system s -- $n$ — Power-law exponent (inverse rate sensitivity) -- $\mathbf{R}^*$ — Lattice rotation matrix tracking crystallographic orientation -- $\rho_{\mathrm{SSD}}$ — Statistically stored dislocation density -- $\rho_{\mathrm{GND}}$ — Geometrically necessary dislocation density -- $\mathbf{L}_p$ — Plastic velocity gradient in the intermediate configuration -- $\tau^s$ — Resolved shear stress on slip system s -- $\mathbf{C}_{\mathrm{crystal}}$ — Single-crystal elastic stiffness tensor in the crystal reference frame -- $R^*_{im}$ — Components of the lattice rotation matrix (Rayleigh product index notation) -- $\star$ — Rayleigh product operator — shorthand for four-index rotation C_ijkl = R_im R_jn R_ko R_lp C_mnop -- $[M]$ — 6x6 Bond transformation matrix for Voigt rotation of stiffness, constructed from R* -- $h_0$ — Initial hardening rate in Voce hardening law -- $\tau_{\mathrm{sat}}$ — Saturation stress in Voce hardening law -- $q^{ss'}$ — Latent hardening ratio between slip systems -- $\Delta t_{\mathrm{crit}}$ — Critical time step for explicit Euler stability of viscoplastic flow - - -## 3. Algorithmic Implementation -**Algorithm: EVP-FFT Polycrystal Simulation** - -$$ -\begin{algorithmic} -\State $Initialize \colon \mathbf{R}^*(\mathbf{x}) \text{ from EBSD/orientation data}, \; \boldsymbol{\varepsilon}^p_0 = \mathbf{0}, \; \rho^s_0 = \rho_{\mathrm{init}}$ -\State $C_{ijkl}(\mathbf{x}) = R^*_{im} R^*_{jn} R^*_{ko} R^*_{lp}\, C_{mnop}^{\mathrm{crystal}}, \; \mathbf{m}^s(\mathbf{x}) = \mathbf{R}^*(\mathbf{x})\,\mathbf{m}^s_0\,\mathbf{R}^{*T}(\mathbf{x})$ -\For{$\text{each load step } n = 1, 2, \ldots$} - \While{$\|\mathrm{div}\,\boldsymbol{\sigma}_k\| > \mathrm{tol}$} - \State $\boldsymbol{\sigma}_k(\mathbf{x}) = \mathbf{C}(\mathbf{x}) \colon (\boldsymbol{\varepsilon}_k(\mathbf{x}) - \boldsymbol{\varepsilon}^p(\mathbf{x}))$ - \State $\dot{\gamma}^s = \dot{\gamma}^s_0 \left(\frac{\mathbf{m}^s(\mathbf{x}) \colon \boldsymbol{\sigma}'(\mathbf{x})}{\tau^s_c(\mathbf{x})}\right)^n$ - \State $\dot{\boldsymbol{\varepsilon}}^p(\mathbf{x}) = \sum_s \mathrm{sym}(\mathbf{m}^s(\mathbf{x}))\,\dot{\gamma}^s$ - \State $\boldsymbol{\varepsilon}^p_{n+1}(\mathbf{x}) = \boldsymbol{\varepsilon}^p_n(\mathbf{x}) + \Delta t\,\dot{\boldsymbol{\varepsilon}}^p(\mathbf{x})$ - \State $\hat{\boldsymbol{\tau}}_k = \mathcal{F}\{\boldsymbol{\sigma}_k - \mathbf{C}^0 \colon \boldsymbol{\varepsilon}_k\}$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\boldsymbol{\xi}) = \bar{\boldsymbol{\varepsilon}} - \hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) \colon \hat{\boldsymbol{\tau}}_k(\boldsymbol{\xi})$ - \State $\boldsymbol{\varepsilon}_{k+1}(\mathbf{x}) = \mathcal{F}^{-1}\{\hat{\boldsymbol{\varepsilon}}_{k+1}\}$ - \EndWhile - \State $\tau^s_c \gets \mu\,b^s\sqrt{\sum_{s'} h^{ss'}\,\rho^{s'}}, \quad \dot{\rho}^s_{\mathrm{SSD}} = \frac{1}{b^s}\left(\frac{1}{l^s} - 2y_c\,\rho^s_{\mathrm{SSD}}\right)|\dot{\gamma}^s|$ - \State $\mathbf{W}_p = \sum_s \dot{\gamma}^s\,\mathrm{skew}(\mathbf{m}^s_0), \; \mathbf{W}_e = \mathbf{W} - \mathbf{W}_p, \; \mathbf{R}^* \gets \mathbf{R}^* + \Delta t\,\mathbf{W}_e\,\mathbf{R}^*$ -\EndFor -\end{algorithmic} -$$ - -**Taichi Mapping:** -The constitutive evaluation (stress, shear rates, plastic strain update) is the bottleneck and is embarrassingly parallel across voxels on GPU. Each voxel stores the rotation matrix R*, plastic strain, and dislocation densities as ti.field history variables. FFT/iFFT for the Lippmann-Schwinger update via cuFFT. Quasi-Newton outer solver recommended to minimize the number of constitutive evaluations per load step. - - -## 4. Known Pitfalls -**Crystal plasticity evaluation is the computational bottleneck:** Evaluating the nonlinear viscoplastic constitutive law at each voxel (resolving shear rates across all slip systems, updating dislocation densities) is far more expensive than the FFT solver operations. The basic scheme requires a full constitutive evaluation at every iteration, making it inefficient. Quasi-Newton or Newton-type solvers that minimize the number of constitutive evaluations are strongly preferred. - - -**Texture update rotation overhead:** At finite strains, tracking the continuous rotation of the crystal lattice via the elastic spin $\mathbf{W}_e$ introduces a time-consuming rotation step at each voxel during constitutive evaluation. This rotation overhead is absent in isotropic composite simulations and can dominate the computational cost for large polycrystalline aggregates. - - -**Gibbs oscillations at grain boundaries:** Sharp transitions in crystallographic orientation at grain boundaries produce spurious high-frequency ringing (Gibbs phenomenon) in the stress and strain fields when using continuous Fourier derivatives. The spatial variability of local fields can be artificially larger than in FEM. Discrete differentiation rules (e.g., Willot rotated staggered grid) are needed to smooth fields and maintain accuracy without prohibitively fine grids. - - -**Strain gradient plasticity requires higher-order derivatives:** Physically-based models that compute geometrically necessary dislocation (GND) densities from $\boldsymbol{\alpha} = -\nabla \times \boldsymbol{\varepsilon}^p$ require computing curl operators in Fourier space. These higher-order derivatives amplify Gibbs oscillations at grain boundaries, demanding even more aggressive smoothing or finer resolution than standard crystal plasticity simulations. - - -**Explicit Euler stability constraint for viscoplastic integration:** When explicit (forward) Euler is used to integrate the viscoplastic flow rule, the critical time step is bounded by $\Delta t_{\mathrm{crit}} \propto \tau^s_c / (n \mu \dot{\gamma}_{\mathrm{active}})$, where $n$ is the power-law exponent and $\mu$ is the shear modulus. As $n$ increases toward rate-independent behavior, $\Delta t_{\mathrm{crit}}$ shrinks drastically and the integration becomes unstable. Implicit backward Euler with a return-mapping algorithm is strongly preferred for large $n$. No CFL-type spatial constraint applies because EVP-FFT is quasi-static (no inertial wave propagation). For the lattice rotation update $\mathbf{R}^* \gets \mathbf{R}^* + \Delta t \mathbf{W}_e \mathbf{R}^*$, the explicit Euler does not preserve orthogonality of $\mathbf{R}^*$; for large rotation increments, use the exponential map $\mathbf{R}^* \gets \exp(\mathbf{W}_e \Delta t) \mathbf{R}^*$ instead. - - -**Basic scheme convergence adequate but slow for nonlinear power laws:** While the low phase contrast (only single-crystal anisotropy) makes the basic scheme stable for polycrystals, highly nonlinear viscoplastic power laws with large $n$ exponents degrade convergence significantly. The basic scheme adds nonlinearity to the implicit equation without tangent information, resulting in many more iterations than necessary. - - -## 5. References -- Schneider (2021) -- FFT polycrystal overview, solver recommendations, VP-FFT and EVP-FFT -- Lebensohn (2001) -- VP-FFT framework for polycrystal plasticity -- Lebensohn et al. (2012) -- EVP-FFT with elasto-viscoplastic constitutive law -- Lucarini et al. (2022) -- Finite-strain polycrystal FFT, DBFFT approach -- Lebensohn and Needleman (2016) -- Strain gradient crystal plasticity with GND via FFT - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-reference-medium.md b/packages/akms/src/akms/_bundled/global_nodes/fft-reference-medium.md deleted file mode 100644 index a854a44..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-reference-medium.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -id: fft-reference-medium -title: Reference Medium Selection -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- fft-galerkin -- homogenization -- convergence -- accelerated-schemes -- spectral -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Reference medium is introduced in the L-S reformulation -- to: fft-solver-basic-scheme - type: feeds-into - weight: 1.0 - note: Basic scheme convergence depends critically on C0 choice -- to: fft-solver-eyre-milton - type: feeds-into - weight: 0.9 - note: Polarization schemes have different optimal C0 -- to: fft-solver-polarization-admm - type: feeds-into - weight: 0.9 - note: ADMM methods converge for any C0 but speed depends on choice -- to: fft-convergence-schemes - type: feeds-into - weight: 0.7 - note: Convergence rates depend on reference medium -context_size: medium -reading_priority: full -load_with: -- fft-lippmann-schwinger -- fft-solver-basic-scheme -content_ref: null -akms_schema: v2 ---- - -# Reference Medium Selection - -## Summary -Reference medium selection determines the convergence behavior of all Lippmann-Schwinger-based FFT solvers. The reference stiffness tensor $\mathbf{C}^0$ is an auxiliary numerical parameter with no physical meaning in the final solution, but it controls the step size of iterative algorithms. For the basic scheme, the optimal choice is the arithmetic mean of extreme phase stiffnesses, with convergence conditional on $\alpha_0 > \alpha_+^2/(2\alpha_-)$. For polarization schemes, convergence is guaranteed for any $\mathbf{C}^0$, with optimal rate at the geometric mean. The iteration count scales linearly with phase contrast for the basic scheme and as $\sqrt{\kappa}$ for Krylov/polarization methods. - - -## 1. Core Concept -The reference medium with stiffness $\mathbf{C}^0$ is introduced to reformulate the heterogeneous equilibrium problem into the Lippmann-Schwinger integral equation. The polarization field $\boldsymbol{\tau} = (\mathbf{C} - \mathbf{C}^0) \colon \boldsymbol{\varepsilon}$ captures the deviation from the reference. While $\mathbf{C}^0$ does not affect the converged solution, it controls the spectral radius of the iteration operator. The basic scheme can be interpreted as a gradient descent with step size proportional to $1/\alpha_0$, making the choice of $\alpha_0$ analogous to learning rate selection. Different solver families (fixed-point, polarization, Krylov) have fundamentally different sensitivities to this choice. - - -## 2. Mathematical Formulation -For nonlinear materials, the convergence bounds are expressed in terms of the Lipschitz constant $\alpha_+$ and monotonicity constant $\alpha_-$ of the stress operator. The reference parameter $\alpha_0$ (for $\mathbf{C}^0 = \alpha_0 \mathbf{Id}$) must satisfy specific bounds depending on the solver family. For linear elasticity, these reduce to conditions on the Lame constants of the constituent phases. - - -**Lipschitz continuity bound:** - -$$ -\|\boldsymbol{\sigma}(\mathbf{x}, \boldsymbol{\varepsilon}_1) - \boldsymbol{\sigma}(\mathbf{x}, \boldsymbol{\varepsilon}_2)\| \le \alpha_+ \|\boldsymbol{\varepsilon}_1 - \boldsymbol{\varepsilon}_2\| -$$ - -where alpha_+ is the upper Lipschitz bound on the stress operator - -**Monotonicity bound:** - -$$ -(\boldsymbol{\sigma}(\mathbf{x}, \boldsymbol{\varepsilon}_1) - \boldsymbol{\sigma}(\mathbf{x}, \boldsymbol{\varepsilon}_2)) : (\boldsymbol{\varepsilon}_1 - \boldsymbol{\varepsilon}_2) \ge \alpha_- \|\boldsymbol{\varepsilon}_1 - \boldsymbol{\varepsilon}_2\|^2 -$$ - -where alpha_- is the lower monotonicity bound (strong monotonicity constant) - -**Basic scheme convergence condition:** - -$$ -\alpha_0 > \frac{\alpha_+^2}{2\alpha_-} -$$ - -where alpha_0 is the scalar reference parameter for C0 = alpha_0 Id - -**Relaxed condition (potential-based stress):** - -$$ -\alpha_0 > \frac{\alpha_+}{2} -$$ - -where Applies when the stress operator derives from a potential (gradient descent interpretation) - -**Optimal C0 for basic scheme (nonlinear):** - -$$ -\alpha_0^{\text{opt}} = \frac{\alpha_- + \alpha_+}{2} -$$ - -where Arithmetic mean of the bounds gives fastest convergence for the basic scheme - -**Optimal C0 for basic scheme (linear, isotropic):** - -$$ -\lambda_0 = \frac{1}{2}\left(\inf_{\mathbf{x}} \lambda(\mathbf{x}) + \sup_{\mathbf{x}} \lambda(\mathbf{x})\right), \quad \mu_0 = \frac{1}{2}\left(\inf_{\mathbf{x}} \mu(\mathbf{x}) + \sup_{\mathbf{x}} \mu(\mathbf{x})\right) -$$ - -where lambda, mu are Lame constants of the phases; inf/sup taken over domain Omega - -**Optimal C0 for polarization schemes (nonlinear):** - -$$ -\alpha_0^{\text{opt}} = \sqrt{\alpha_- \alpha_+} -$$ - -where Geometric mean of the bounds for Eyre-Milton, ADMM, and augmented Lagrangian - -**Optimal C0 for polarization schemes (linear, isotropic):** - -$$ -\lambda_0 = \sqrt{\inf_{\mathbf{x}} \lambda(\mathbf{x}) \cdot \sup_{\mathbf{x}} \lambda(\mathbf{x})}, \quad \mu_0 = \sqrt{\inf_{\mathbf{x}} \mu(\mathbf{x}) \cdot \sup_{\mathbf{x}} \mu(\mathbf{x})} -$$ - -where Geometric mean of extreme Lame constants for polarization schemes - -**Notation:** - -- $\alpha_0$ — Scalar reference medium parameter (C0 = alpha_0 Id) -- $\alpha_+$ — Lipschitz constant of the stress operator (upper bound) -- $\alpha_-$ — Strong monotonicity constant (lower bound) -- $\lambda_0, \mu_0$ — Lame constants of the reference medium -- $\lambda, \mu$ — Local Lame constants of the constituent phases -- $\kappa$ — Phase contrast ratio alpha_+/alpha_- - - -## 3. Algorithmic Implementation -Not applicable — reference medium selection is a parameter choice, not an algorithm. The selection formulas are in the mathematical formulation section. - -## 4. Known Pitfalls -**Divergence from too-soft reference:** Choosing $\mathbf{C}^0$ too soft (below the convergence bound) corresponds to an overly large gradient descent step size and causes the basic scheme to globally diverge. There is no automatic recovery — the simulation simply fails with growing residuals. - - -**Linear contrast scaling for basic scheme:** The basic scheme requires iterations proportional to the phase contrast ratio $\kappa$. For high-contrast composites (e.g., $\kappa > 100$), the basic scheme becomes impractically slow even with optimal $\mathbf{C}^0$. Krylov and polarization methods reduce this to $\sqrt{\kappa}$. - - -**Different optima for different solvers:** The arithmetic mean (basic scheme) and geometric mean (polarization schemes) give different optimal $\mathbf{C}^0$. Using the basic-scheme optimum in a polarization method (or vice versa) will work but converge suboptimally. Always match the formula to the solver. - - -**Nonlinear material parameter estimation:** For nonlinear materials, the Lipschitz and monotonicity constants $\alpha_+$ and $\alpha_-$ may be strain-dependent and difficult to estimate a priori. Overestimating $\alpha_+$ or underestimating $\alpha_-$ leads to a conservative (slow) reference medium choice. - - -**Porous/void phases have alpha_- = 0:** For porous materials, the monotonicity constant $\alpha_- = 0$ (void has zero stiffness), making the convergence bound $\alpha_0 > \alpha_+^2/(2\alpha_-)$ impossible to satisfy. The basic scheme fundamentally cannot converge for infinite contrast. Polarization schemes or displacement-based methods are required. - - -## 5. References -- Schneider (2021) — §3.1: basic scheme convergence bounds, §3.5: polarization scheme reference medium -- Lucarini et al. (2022) — §3.2: reference medium role - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-barzilai-borwein.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-barzilai-borwein.md deleted file mode 100644 index cafb0d0..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-barzilai-borwein.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -id: fft-solver-barzilai-borwein -title: Barzilai-Borwein Accelerated Basic Scheme -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- fft-galerkin -- spectral -- convergence -- accelerated-schemes -- iterative -- spectral-step-size -- quasi-newton -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-solver-basic-scheme - type: requires - weight: 1.0 - note: BB method modifies the basic scheme by replacing fixed step size with adaptive spectral step -- to: fft-lippmann-schwinger - type: requires - weight: 0.9 - note: Iterates on the Lippmann-Schwinger equation with adaptive reference stiffness -- to: fft-green-operator - type: requires - weight: 0.9 - note: Uses the Green's operator for the strain update in Fourier space -- to: fft-reference-medium - type: requires - weight: 0.7 - note: BB bypasses manual reference medium selection via adaptive step size -- to: fft-solver-fast-gradient - type: refines - weight: 0.6 - note: Both are gradient-based accelerations of the basic scheme -- to: fft-solver-nonlinear-cg - type: refines - weight: 0.7 - note: Comparable iteration count to Fletcher-Reeves nonlinear CG in benchmarks -- to: fft-convergence-schemes - type: feeds-into - weight: 0.6 - note: Competitive convergence for moderate and high contrast -context_size: medium -reading_priority: full -load_with: -- fft-solver-basic-scheme -- fft-reference-medium -content_ref: null -akms_schema: v2 ---- - -# Barzilai-Borwein Accelerated Basic Scheme - -## Summary -The Barzilai-Borwein (BB) method accelerates the basic scheme by replacing the fixed reference medium parameter with an adaptive spectral step size computed from successive strain and stress differences. It can be interpreted as L-BFGS of depth one without line search, or equivalently as gradient descent with an adaptive learning rate. The spectral step size $\alpha_k$ is computed as the Rayleigh quotient of the stress-strain increment, requiring no manual parameter tuning. The method is highly competitive with the fastest nonlinear solvers (Fletcher-Reeves CG, L-BFGS of depth four) while requiring only 2 strain fields in memory and two FFT evaluations per iteration. A defining characteristic is its inherent non-monotonicity: the residual fluctuates between iterations but maintains a rapid overall downward trajectory. - - -## 1. Core Concept -The Barzilai-Borwein method modifies the basic scheme by dynamically adapting the effective reference medium stiffness at each iteration. Instead of using a fixed $\alpha_0$, it computes a spectral step size $\alpha_k$ from the inner product of successive stress and strain differences divided by the squared norm of the strain difference. This is equivalent to a secant approximation of the local curvature of the energy landscape, matching the L-BFGS interpretation of depth one. The adaptive step size eliminates the need for manual reference medium selection and automatically adjusts to the local nonlinearity. The resulting method is parameter-free, memory-efficient, and achieves convergence rates comparable to much more complex solvers. The non-monotone residual behavior is characteristic of spectral gradient methods and does not indicate instability. - - -## 2. Mathematical Formulation -The BB method replaces the constant reference parameter $\alpha_0$ in the basic scheme with an iteration-dependent parameter $\alpha_k$ computed from the Rayleigh quotient of successive stress and strain differences. The update formula is structurally identical to the basic scheme but with $1/\alpha_k$ scaling the Green's operator application instead of $1/\alpha_0$. - - -**Spectral step size (Barzilai-Borwein):** - -$$ -\alpha_k = \frac{\langle \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_k) - \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_{k-1}), \; \boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1} \rangle_{L^2}}{\|\boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1}\|^2_{L^2}} -$$ - -where sigma(epsilon_k) is the stress at iteration k, the inner product and norm are L^2 over the unit cell - -**BB-accelerated basic scheme iteration:** - -$$ -\boldsymbol{\varepsilon}_{k+1} = \bar{\boldsymbol{\varepsilon}} - \frac{1}{\alpha_k} \boldsymbol{\Gamma} \colon \left( \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_k) - \mathbf{C}^0 \colon \boldsymbol{\varepsilon}_k \right) -$$ - -where Gamma is the (non-dimensional) Green's operator, C^0 is the formal reference stiffness - -**Interpretation as L-BFGS depth one:** - -$$ -\alpha_k \approx \frac{\mathbf{y}_k^T \mathbf{s}_k}{\mathbf{s}_k^T \mathbf{s}_k}, \quad \mathbf{s}_k = \boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1}, \quad \mathbf{y}_k = \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_k) - \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_{k-1}) -$$ - -where s_k is the strain step, y_k is the stress step; this is the standard secant (BB1) formula - -**Notation:** - -- $\alpha_k$ — Adaptive spectral step size at iteration k -- $\boldsymbol{\varepsilon}_k$ — Strain field at iteration k -- $\boldsymbol{\sigma}$ — Nonlinear stress operator -- $\boldsymbol{\Gamma}$ — Non-dimensional Green's operator -- $\mathbf{C}^0$ — Formal reference stiffness (used in polarization) -- $\langle \cdot, \cdot \rangle_{L^2}$ — L^2 inner product over the unit cell - - -## 3. Algorithmic Implementation -**Algorithm: Barzilai-Borwein Accelerated Basic Scheme** - -$$ -\begin{algorithmic} -\State $\boldsymbol{\varepsilon}_0(\mathbf{x}) \leftarrow \bar{\boldsymbol{\varepsilon}}$ -\State $\text{Run one basic scheme step to obtain } \boldsymbol{\varepsilon}_1$ -\For{$k = 1, 2, \ldots$} - \State $\boldsymbol{\sigma}_k \leftarrow \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_k)$ - \State $\alpha_k \leftarrow \frac{\langle \boldsymbol{\sigma}_k - \boldsymbol{\sigma}_{k-1}, \; \boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1} \rangle_{L^2}}{\|\boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1}\|^2_{L^2}}$ - \State $\boldsymbol{\tau}_k \leftarrow \boldsymbol{\sigma}_k - \mathbf{C}^0 \colon \boldsymbol{\varepsilon}_k$ - \State $\hat{\boldsymbol{\tau}}_k \leftarrow \text{DFT}(\boldsymbol{\tau}_k)$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\boldsymbol{\xi}) \leftarrow -\frac{1}{\alpha_k}\hat{\boldsymbol{\Gamma}}(\boldsymbol{\xi}) \colon \hat{\boldsymbol{\tau}}_k(\boldsymbol{\xi}) \quad \forall \boldsymbol{\xi} \neq \mathbf{0}$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\mathbf{0}) \leftarrow \bar{\boldsymbol{\varepsilon}}$ - \State $\boldsymbol{\varepsilon}_{k+1} \leftarrow \text{DFT}^{-1}(\hat{\boldsymbol{\varepsilon}}_{k+1})$ - \If{$\|\boldsymbol{\Gamma} \colon \boldsymbol{\sigma}_k\|_{L^2} / \|\langle \boldsymbol{\sigma}_k \rangle\| < \text{tol}$} - \State \textbf{break} - \EndIf -\EndFor -\end{algorithmic} -$$ - -**Taichi Mapping:** -Inner product and norm computations for alpha_k map to a Taichi parallel reduction kernel. Stress evaluation, polarization, and Green's operator application are the same pointwise kernels as the basic scheme. The previous stress field sigma_{k-1} must be stored alongside the current strain, giving the 2-field memory footprint. - - -## 4. Known Pitfalls -**Non-monotone residual:** The residual in the BB scheme fluctuates and can temporarily increase between iterations. This non-monotonicity is inherent to spectral gradient methods and should not be interpreted as divergence. Convergence monitoring must use a running minimum or averaged residual rather than checking strict monotonic decrease. - - -**First iteration bootstrap:** The spectral step size $\alpha_k$ requires both the current and previous strain-stress pairs. The first iteration (k=0 to k=1) must use the standard basic scheme with a manually chosen reference medium, or a default initial step. Poor initialization of $\alpha_0$ can lead to a large first residual spike. - - -**Degenerate step size for nearly homogeneous fields:** When $\boldsymbol{\varepsilon}_k \approx \boldsymbol{\varepsilon}_{k-1}$ (near convergence or for nearly homogeneous microstructures), the denominator $\|\boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1}\|^2$ approaches zero, making $\alpha_k$ numerically unstable. A safeguard (e.g., clamping $\alpha_k$ to a bounded range) is needed in practice. - - -**No convergence guarantee for general nonlinearity:** Unlike the basic scheme which has a rigorous convergence proof for sufficiently stiff reference media, the BB method lacks a general convergence guarantee for non-convex or non-smooth problems. In practice it is robust, but theoretical convergence is established only for strongly convex objectives with Lipschitz gradients. - - -**Not suitable for non-smooth constitutive laws:** The secant approximation underlying the BB step size assumes smooth stress-strain relationships. For materials with yield surfaces or damage thresholds that introduce discontinuities in the tangent, the BB step size can become erratic. In such cases, Newton-Krylov methods may be more appropriate. - - -## 5. References -- Schneider (2021) -- review of nonlinear FFT-based computational homogenization, Barzilai-Borwein method and L-BFGS interpretation -- Lucarini et al. (2022) -- non-linear quasi-Newton approaches for FFT homogenization - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-basic-scheme.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-basic-scheme.md deleted file mode 100644 index 27a6a4d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-basic-scheme.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -id: fft-solver-basic-scheme -title: Basic Scheme (Moulinec-Suquet Fixed Point) -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- fft-galerkin -- spectral -- convergence -- iterative -- fixed-point -- gradient-descent -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Basic scheme is the fixed-point iteration on the Lippmann-Schwinger equation -- to: fft-green-operator - type: requires - weight: 1.0 - note: Uses the Eshelby-Green operator Gamma^0 as the projection kernel -- to: fft-reference-medium - type: requires - weight: 0.9 - note: Convergence depends critically on reference medium parameter alpha_0 -- to: fft-discretization-moulinec-suquet - type: requires - weight: 0.8 - note: Originally formulated with trigonometric collocation discretization -- to: fft-solver-barzilai-borwein - type: feeds-into - weight: 0.9 - note: BB method replaces fixed step size with adaptive spectral step -- to: fft-solver-fast-gradient - type: feeds-into - weight: 0.8 - note: Fast gradient methods augment the basic scheme with momentum -- to: fft-solver-nonlinear-cg - type: feeds-into - weight: 0.8 - note: Nonlinear CG generalizes gradient descent with conjugate directions -- to: fft-convergence-schemes - type: feeds-into - weight: 0.7 - note: Convergence rate analysis depends on contrast ratio kappa -context_size: medium -reading_priority: full -load_with: -- fft-lippmann-schwinger -- fft-reference-medium -- fft-green-operator -content_ref: null -akms_schema: v2 ---- - -# Basic Scheme (Moulinec-Suquet Fixed Point) - -## Summary -The basic scheme is the foundational fixed-point iteration for FFT-based computational homogenization, introduced by Moulinec and Suquet. It iteratively solves the Lippmann-Schwinger equation by computing the stress polarization in real space, applying the Green's operator via FFT in Fourier space, and updating the strain field. The method can be interpreted as gradient descent on the total condensed elastic energy, with the reference medium stiffness controlling the algorithmic step size. Convergence is globally linear and mesh-independent, but the iteration count scales linearly with the phase contrast ratio $\kappa = \alpha_+/\alpha_-$, making it impractically slow for high-contrast composites. Memory footprint is minimal (1 strain field), and each iteration requires exactly two FFT evaluations. The method fails for infinite contrast (porous or rigid inclusions) when using trigonometric polynomial discretizations. - - -## 1. Core Concept -The basic scheme iterates the Lippmann-Schwinger equation as a fixed-point method. Given a reference medium with isotropic stiffness $\mathbf{C}^0 = \alpha_0 \mathbf{Id}$, the stress polarization $\boldsymbol{\tau}_k = \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_k) - \mathbf{C}^0 \colon \boldsymbol{\varepsilon}_k$ is computed pointwise in real space from the current strain iterate, then convolved with the Green's operator $\boldsymbol{\Gamma}^0$ via FFT to obtain the updated strain field. This is mathematically equivalent to gradient descent on the total condensed elastic energy $W(\mathbf{u}) = \int_Y w(\mathbf{x}, \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}) \, d\mathbf{x}$ with step size $s_k = 1/(2\mu_0)$. If the reference material is sufficiently stiff (small step size), the energy decreases monotonically. If too soft (large step size), the explicit gradient update becomes unstable. The iteration count is bounded independently of mesh resolution but grows linearly with the material contrast ratio, explaining why the method is practical only for moderate contrast composites. - - -## 2. Mathematical Formulation -The basic scheme update computes the next strain iterate from the current one by evaluating the nonlinear stress response, forming the polarization with respect to the reference medium, and applying the Green's operator. The convergence condition on $\alpha_0$ depends on the Lipschitz constant $\alpha_+$ and monotonicity constant $\alpha_-$ of the stress operator, with different bounds for general and potential-based nonlinearity. The optimal reference medium for the basic scheme is the arithmetic mean of the material bounds. - - -**Basic scheme fixed-point iteration:** - -$$ -\boldsymbol{\varepsilon}_{k+1} = \bar{\boldsymbol{\varepsilon}} - \boldsymbol{\Gamma}^0 \colon \left( \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_k) - \mathbf{C}^0 \colon \boldsymbol{\varepsilon}_k \right), \quad k = 0, 1, \ldots -$$ - -where epsilon-bar is the prescribed macroscopic strain, Gamma^0 is the Green's operator, sigma is the nonlinear stress, C^0 is the reference stiffness - -**Convergence condition (general nonlinearity):** - -$$ -\alpha_0 > \frac{\alpha_+^2}{2\alpha_-} -$$ - -where alpha_+ is the Lipschitz constant, alpha_- is the monotonicity constant of the stress operator - -**Fastest theoretical rate (general nonlinearity):** - -$$ -\alpha_0^{\text{opt}} = \frac{\alpha_+^2}{\alpha_-} -$$ - -where This gives the smallest contraction factor for the general case - -**Convergence condition (potential-based stress):** - -$$ -\alpha_0 > \frac{\alpha_+}{2} -$$ - -where Less restrictive bound when stress derives from a potential (symmetric positive definite tangent) - -**Optimal reference medium (potential-based):** - -$$ -\alpha_0^{\text{opt}} = \frac{\alpha_+ + \alpha_-}{2} -$$ - -where Arithmetic mean of bounds; convergence rate is (alpha_+ - alpha_-)/(alpha_+ + alpha_-) - -**Gradient descent interpretation:** - -$$ -\mathbf{u}_{k+1} = \mathbf{u}_k - s_k \nabla W(\mathbf{u}_k), \quad s_k = \frac{1}{2\mu_0} -$$ - -where W is the total condensed elastic energy, nabla W = G dw/depsilon, mu_0 is the reference shear modulus - -**Optimal reference (linear isotropic):** - -$$ -\lambda_0 = \frac{1}{2}\left(\inf_{\mathbf{x}} \lambda(\mathbf{x}) + \sup_{\mathbf{x}} \lambda(\mathbf{x})\right), \quad \mu_0 = \frac{1}{2}\left(\inf_{\mathbf{x}} \mu(\mathbf{x}) + \sup_{\mathbf{x}} \mu(\mathbf{x})\right) -$$ - -where Arithmetic mean of extreme Lame constants across the microstructure - -**Notation:** - -- $\boldsymbol{\varepsilon}_k$ — Strain field at iteration k -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain -- $\boldsymbol{\Gamma}^0$ — Eshelby-Green operator of the reference medium -- $\mathbf{C}^0$ — Reference medium stiffness tensor (C^0 = alpha_0 Id) -- $\boldsymbol{\sigma}$ — Nonlinear stress operator -- $\alpha_0$ — Scalar reference medium parameter -- $\alpha_+$ — Lipschitz constant of the stress operator -- $\alpha_-$ — Strong monotonicity constant -- $\kappa$ — Phase contrast ratio alpha_+/alpha_- -- $W$ — Total condensed elastic energy functional - - -## 3. Algorithmic Implementation -**Algorithm: Basic Scheme (Moulinec-Suquet)** - -$$ -\begin{algorithmic} -\State $\boldsymbol{\varepsilon}_0(\mathbf{x}) \leftarrow \bar{\boldsymbol{\varepsilon}}$ -\While{$\|\boldsymbol{\Gamma} \colon \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_k)\|_{L^2} / \|\langle \boldsymbol{\sigma}_k \rangle\| > \text{tol}$} - \State $\boldsymbol{\tau}_k(\mathbf{x}) \leftarrow \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_k(\mathbf{x})) - \mathbf{C}^0 \colon \boldsymbol{\varepsilon}_k(\mathbf{x})$ - \State $\hat{\boldsymbol{\tau}}_k \leftarrow \text{DFT}(\boldsymbol{\tau}_k)$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\boldsymbol{\xi}) \leftarrow -\hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) \colon \hat{\boldsymbol{\tau}}_k(\boldsymbol{\xi}) \quad \forall \boldsymbol{\xi} \neq \mathbf{0}$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\mathbf{0}) \leftarrow \bar{\boldsymbol{\varepsilon}}$ - \State $\boldsymbol{\varepsilon}_{k+1} \leftarrow \text{DFT}^{-1}(\hat{\boldsymbol{\varepsilon}}_{k+1})$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -Pointwise stress and polarization evaluation maps to a Taichi kernel over the voxel grid. Forward and inverse FFT use ti.fft (or cuFFT via wrapper). Green's operator application is a pointwise kernel in Fourier space. The entire iteration loop runs on GPU with only the convergence check requiring a global reduction. - - -## 4. Known Pitfalls -**Linear scaling with contrast ratio:** The iteration count scales linearly with $\kappa = \alpha_+/\alpha_-$. For high-contrast composites ($\kappa > 100$), the basic scheme requires hundreds or thousands of iterations. Krylov and polarization methods reduce this to $\sqrt{\kappa}$ scaling. For moderate contrast ($\kappa < 10$), the basic scheme remains competitive due to its minimal memory footprint and simplicity. - - -**Divergence for infinite contrast:** The basic scheme fundamentally cannot converge for porous materials ($\alpha_- = 0$) or rigid inclusions ($\alpha_+ = \infty$) because the convergence bound $\alpha_0 > \alpha_+^2/(2\alpha_-)$ cannot be satisfied. With trigonometric polynomial discretizations, the global nature of the basis functions causes boundary errors at pore-solid interfaces to propagate across the entire domain, leading to the average stress falsely converging to zero. - - -**Reference medium sensitivity:** Choosing $\mathbf{C}^0$ too soft corresponds to an excessively large gradient descent step size, causing global instability. Choosing it too stiff yields impractically slow convergence. The optimal choice (arithmetic mean of phase stiffnesses) requires knowledge of the extreme material constants, which may be difficult to estimate for nonlinear materials. - - -**One constitutive evaluation per iteration:** Every iteration requires a full evaluation of the nonlinear constitutive law across all voxels. For expensive material models (crystal plasticity, finite strain), this dominates the computational cost. Newton-Krylov methods amortize expensive constitutive evaluations by solving the linearized system to high accuracy within each Newton step. - - -**No improvement from mesh refinement:** While the iteration count is bounded independently of the mesh size (a positive feature for scalability), increasing resolution does not accelerate convergence. The convergence rate depends solely on the material contrast and reference medium choice. - - -## 5. References -- Schneider (2021) -- review of nonlinear FFT-based computational homogenization, basic scheme and gradient descent interpretation -- Lucarini et al. (2022) -- basic scheme formulation, convergence criteria, and reference medium selection - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-eyre-milton.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-eyre-milton.md deleted file mode 100644 index 26e23bb..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-eyre-milton.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -id: fft-solver-eyre-milton -title: Eyre-Milton Accelerated Scheme -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- polarization -- fft-galerkin -- convergence -- accelerated-schemes -- iterative -- operator-splitting -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: Rewrites the Lippmann-Schwinger equation for the polarization field -- to: fft-green-operator - type: requires - weight: 1.0 - note: Helmholtz reflection operator Y^0 = Id - 2C^0 Gamma^0 built from the Green's operator -- to: fft-reference-medium - type: requires - weight: 0.9 - note: Optimal reference stiffness is geometric mean alpha_0 = sqrt(alpha_- alpha_+) -- to: fft-solver-basic-scheme - type: requires - weight: 0.8 - note: Generalizes the basic scheme via Cayley transform and Peaceman-Rachford splitting -- to: fft-solver-polarization-admm - type: refines - weight: 0.9 - note: Eyre-Milton is Peaceman-Rachford splitting (gamma=0); ADMM is Douglas-Rachford (gamma=1/2) -- to: fft-convergence-schemes - type: feeds-into - weight: 0.7 - note: Achieves sqrt(kappa) convergence, matching the optimal Krylov rate -- to: fft-solver-krylov-cg - type: feeds-into - weight: 0.6 - note: Matches CG worst-case convergence rate with lower memory footprint -context_size: medium -reading_priority: full -load_with: -- fft-solver-polarization-admm -- fft-reference-medium -- fft-green-operator -content_ref: null -akms_schema: v2 ---- - -# Eyre-Milton Accelerated Scheme - -## Summary -The Eyre-Milton accelerated scheme reformulates the Lippmann-Schwinger equation as a fixed-point iteration on the polarization field using the Cayley transform and the Helmholtz reflection operator. It corresponds to the Peaceman-Rachford operator splitting with zero damping ($\gamma = 0$). The method converges linearly for any reference material $\mathbf{C}^0$ and any initial polarization, with the iteration count scaling as $\sqrt{\kappa}$ (square root of the contrast ratio) under the optimal geometric mean reference stiffness $\alpha_0 = \sqrt{\alpha_- \alpha_+}$. This matches the fastest Krylov solvers while requiring only 2 fields in memory. - - -## 1. Core Concept -The key insight is to rewrite the Lippmann-Schwinger equation in terms of the polarization field $P = \frac{\partial w}{\partial \varepsilon} + \mathbf{C}^0 \colon \varepsilon$ and construct a fixed-point iteration using two non-expansive operators. The Cayley transform $\mathcal{Z}_0(P) = (\frac{\partial w}{\partial \varepsilon} - \mathbf{C}^0)(\frac{\partial w}{\partial \varepsilon} + \mathbf{C}^0)^{-1}(P)$ maps the nonlinear constitutive law into an $L^2$-contraction for every choice of reference medium, while the Helmholtz reflection operator $\mathcal{Y}^0 = \mathbf{Id} - 2\mathbf{C}^0 \colon \Gamma^0$ provides the non-expansive projection onto compatible fields. The composition $\mathcal{Y}^0 \colon \mathcal{Z}_0$ is contractive, guaranteeing convergence. Unlike the basic scheme where the reference medium must be sufficiently stiff for stability, the Eyre-Milton method converges for any $\mathbf{C}^0$, with the geometric mean reference giving the fastest rate proportional to $\sqrt{\kappa}$ rather than the linear $\kappa$ scaling of the basic scheme. - - -## 2. Mathematical Formulation -The Eyre-Milton iteration updates the polarization field using the Helmholtz reflection operator applied to the Cayley transform. The Cayley transform acts as a pointwise nonlinear solve at each grid point, while the Helmholtz reflection involves a global FFT-based convolution. The convergence rate depends on the spectral radius of the composition of these two operators. - - -**Eyre-Milton polarization iteration:** - -$$ -P_{k+1} = 2\mathbf{C}^0 \colon \bar{\varepsilon} + \mathcal{Y}^0 \colon \mathcal{Z}_0(P_k) -$$ - -where P_k is the polarization at iteration k, Y^0 is the Helmholtz reflection operator, Z_0 is the Cayley transform - -**Helmholtz reflection operator:** - -$$ -\mathcal{Y}^0 = \mathbf{Id} - 2\mathbf{C}^0 \colon \Gamma^0 -$$ - -where Gamma^0 is the Green's operator; Y^0 is non-expansive in the C^0-weighted L^2 norm - -**Cayley transform of the nonlinear stress operator:** - -$$ -\mathcal{Z}_0(P) = \left(\frac{\partial w}{\partial \varepsilon} - \mathbf{C}^0\right)\left(\frac{\partial w}{\partial \varepsilon} + \mathbf{C}^0\right)^{-1}(P) -$$ - -where w is the condensed free energy; Z_0 is an L^2-contraction for any reference C^0 - -**Cayley transform explicit form:** - -$$ -\mathcal{Z}_0(P) = P - 2\mathbf{C}^0 \colon \left(\frac{\partial w}{\partial \varepsilon} + \mathbf{C}^0\right)^{-1}(P) -$$ - -where Equivalent form requiring a single local nonlinear solve per grid point - -**Optimal reference stiffness:** - -$$ -\alpha_0^{\text{opt}} = \sqrt{\alpha_- \alpha_+} -$$ - -where Geometric mean of monotonicity and Lipschitz bounds; convergence rate proportional to sqrt(alpha_+/alpha_-) - -**Convergence rate scaling:** - -$$ -\text{iterations} \sim \sqrt{\kappa}, \quad \kappa = \frac{\alpha_+}{\alpha_-} -$$ - -where kappa is the material contrast ratio; compared to linear kappa scaling for the basic scheme - -**Notation:** - -- $P_k$ — Polarization field at iteration k -- $\mathcal{Y}^0$ — Helmholtz reflection operator -- $\mathcal{Z}_0$ — Cayley transform of the nonlinear stress operator -- $\mathbf{C}^0$ — Reference medium stiffness tensor -- $\Gamma^0$ — Green's operator of the reference medium -- $\alpha_0$ — Scalar reference medium parameter -- $\alpha_+$ — Lipschitz constant of the stress operator -- $\alpha_-$ — Strong monotonicity (convexity) constant -- $\kappa$ — Material contrast ratio alpha_+/alpha_- - - -## 3. Algorithmic Implementation -**Algorithm: Eyre-Milton Accelerated Scheme** - -$$ -\begin{algorithmic} -\State $P_0(\mathbf{x}) \leftarrow 2\mathbf{C}^0 \colon \bar{\varepsilon}$ -\State $\alpha_0 \leftarrow \sqrt{\alpha_- \alpha_+}$ -\While{$\|P_{k+1} - P_k\|_{L^2} / \|P_{k+1}\|_{L^2} > \text{tol}$} - \State $e_k \leftarrow \left(\frac{\partial w}{\partial \varepsilon} + \mathbf{C}^0\right)^{-1}(P_k) \quad \text{(local nonlinear solve per voxel)}$ - \State $\mathcal{Z}_0(P_k) \leftarrow P_k - 2\mathbf{C}^0 \colon e_k$ - \State $\hat{Q}_k \leftarrow \text{DFT}(\mathcal{Z}_0(P_k))$ - \State $\hat{R}_k(\boldsymbol{\xi}) \leftarrow \hat{Q}_k(\boldsymbol{\xi}) - 2\mathbf{C}^0 \colon \hat{\Gamma}^0(\boldsymbol{\xi}) \colon \hat{Q}_k(\boldsymbol{\xi}) \quad \forall \boldsymbol{\xi} \neq \mathbf{0}$ - \State $\hat{R}_k(\mathbf{0}) \leftarrow \hat{Q}_k(\mathbf{0})$ - \State $P_{k+1} \leftarrow 2\mathbf{C}^0 \colon \bar{\varepsilon} + \text{DFT}^{-1}(\hat{R}_k)$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -The local nonlinear solve for the Cayley transform maps to a Taichi parallel kernel over all voxels. The Helmholtz reflection decomposes into a forward FFT, pointwise Fourier-space kernel applying Id - 2C^0 Gamma^0, and inverse FFT. Convergence check requires a parallel reduction for the L^2 norm. Total memory is 2 polarization fields (P_k and P_{k+1}). - - -## 4. Known Pitfalls -**Local nonlinear solve for the Cayley transform:** Each iteration requires inverting $(\frac{\partial w}{\partial \varepsilon} + \mathbf{C}^0)$ at every grid point. For complex nonlinear constitutive laws (e.g., crystal plasticity), this local Newton iteration can be expensive. The cost per iteration is comparable to ADMM but higher than the basic scheme, which only evaluates the forward stress operator. - - -**No direct access to stress and strain fields:** The Eyre-Milton scheme iterates on the polarization field $P$, not on strain or stress directly. Extracting the physical strain and stress fields for post-processing requires an additional recovery step after convergence. The compatible strain is $\varepsilon = \bar{\varepsilon} - \Gamma^0 \colon P$ and the stress is $\sigma = P - \mathbf{C}^0 \colon \varepsilon$. - - -**Convergence criterion differs from gradient-based solvers:** The natural convergence measure is the relative change in the polarization $\|P_{k+1} - P_k\|/\|P_{k+1}\|$, not the equilibrium residual used by gradient-based schemes. This makes direct comparison of stopping tolerances across solver families non-trivial. - - -**Geometric mean reference medium differs from basic scheme:** The optimal reference for Eyre-Milton is the geometric mean $\sqrt{\alpha_- \alpha_+}$, whereas the basic scheme uses the arithmetic mean $(\alpha_+ + \alpha_-)/2$. Reusing the basic scheme reference medium in the Eyre-Milton method will yield suboptimal convergence. This difference is especially significant for high-contrast materials. - - -## 5. References -- Schneider (2021) -- review of nonlinear FFT-based computational homogenization, Eyre-Milton scheme and Peaceman-Rachford interpretation -- Eyre and Milton (1999) -- original polarization-based accelerated scheme for composites -- Lucarini et al. (2022) -- operator splitting framework unifying Douglas-Rachford and Peaceman-Rachford for FFT homogenization - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-fast-gradient.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-fast-gradient.md deleted file mode 100644 index 891efde..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-fast-gradient.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -id: fft-solver-fast-gradient -title: Fast Gradient Methods (Nesterov-Type) -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- fft-galerkin -- spectral -- convergence -- accelerated-schemes -- iterative -- nesterov -- momentum -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-solver-basic-scheme - type: requires - weight: 1.0 - note: Fast gradient methods augment the basic scheme's gradient descent with momentum -- to: fft-lippmann-schwinger - type: requires - weight: 0.9 - note: Operates on the Lippmann-Schwinger equation with momentum acceleration -- to: fft-green-operator - type: requires - weight: 0.9 - note: Uses the Green's operator for strain update in Fourier space -- to: fft-reference-medium - type: requires - weight: 0.8 - note: Step size and momentum parameters depend on material bounds alpha_+/alpha_- -- to: fft-solver-barzilai-borwein - type: refines - weight: 0.6 - note: Both accelerate gradient descent; BB is adaptive, Nesterov uses fixed parameters -- to: fft-solver-nonlinear-cg - type: refines - weight: 0.7 - note: Nonlinear CG typically outperforms Nesterov in FFT benchmarks -- to: fft-convergence-schemes - type: feeds-into - weight: 0.7 - note: Achieves optimal sqrt(kappa) convergence rate for strongly convex problems -context_size: medium -reading_priority: full -load_with: -- fft-solver-basic-scheme -- fft-reference-medium -content_ref: null -akms_schema: v2 ---- - -# Fast Gradient Methods (Nesterov-Type) - -## Summary -Fast gradient methods augment the basic scheme's plain gradient descent with a momentum term, accelerating convergence from linear $O(\kappa)$ to optimal $O(\sqrt{\kappa})$ scaling. Two variants exist: the heavy ball method evaluates the gradient at the current iterate and adds momentum to the update, while Nesterov's method evaluates the gradient at an extrapolated point that incorporates momentum. Both can be interpreted as time discretizations of a damped Newtonian dynamical system. For FFT-based homogenization, the Nesterov variant with parameters $s_k = 1/\alpha_+$ and $\beta_k = (\sqrt{\alpha_+} - \sqrt{\alpha_-})/(\sqrt{\alpha_+} + \sqrt{\alpha_-})$ provides guaranteed convergence for strongly convex problems with Lipschitz gradients. Memory footprint is 2 strain fields with two FFT evaluations per iteration. In practice, the methods suffer from sensitive parameter selection and lag behind BB and nonlinear CG by a factor of 2-3 in iteration count even with adaptive restart strategies. - - -## 1. Core Concept -Fast gradient methods improve upon the basic scheme by incorporating inertia from previous iterates, analogous to a physical system with momentum. In Nesterov's formulation, the gradient is evaluated not at the current strain $\boldsymbol{\varepsilon}_k$ but at an extrapolated point $\mathbf{e}_k = \boldsymbol{\varepsilon}_k + \beta_k(\boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1})$ that "looks ahead" along the trajectory. This extrapolation allows the method to accelerate through flat regions of the energy landscape while maintaining stability. The heavy ball variant instead evaluates the gradient at $\boldsymbol{\varepsilon}_k$ and adds the momentum term directly to the strain update. Both methods arise as discretizations of the ODE $\ddot{\mathbf{u}}(t) + b \dot{\mathbf{u}}(t) = -\nabla W(\mathbf{u}(t))$ with damping coefficient $b$. The optimal parameters require knowledge of the Lipschitz constant $\alpha_+$ and strong convexity constant $\alpha_-$, which are often difficult to estimate for nonlinear materials, motivating the use of adaptive restart strategies. - - -## 2. Mathematical Formulation -The two fast gradient variants differ in where the gradient is evaluated and in the optimal parameter selection. The heavy ball method has a slightly faster theoretical rate but requires the stress operator to derive from a potential. Nesterov's method applies to general strongly convex functions with Lipschitz gradients. Both achieve the optimal $\sqrt{\kappa}$ iteration scaling. - - -**Nesterov extrapolated point:** - -$$ -\mathbf{e}_k = \boldsymbol{\varepsilon}_k + \beta_k (\boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1}) -$$ - -where beta_k is the momentum parameter, epsilon_{k-1} is the previous strain iterate - -**Nesterov strain update:** - -$$ -\boldsymbol{\varepsilon}_{k+1} = \bar{\boldsymbol{\varepsilon}} - s_k \boldsymbol{\Gamma} \colon \left( \boldsymbol{\sigma}(\mathbf{e}_k) - \frac{1}{s_k} \mathbf{e}_k \right) -$$ - -where s_k is the step size, Gamma is the Green's operator, sigma is evaluated at the extrapolated point - -**Nesterov optimal parameters:** - -$$ -s_k = \frac{1}{\alpha_+}, \quad \beta_k = \frac{\sqrt{\alpha_+} - \sqrt{\alpha_-}}{\sqrt{\alpha_+} + \sqrt{\alpha_-}} -$$ - -where alpha_+ is the Lipschitz constant, alpha_- is the strong convexity constant - -**Nesterov convergence estimate:** - -$$ -\|\boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}^*\|_{L^2} \le C \left(1 - \sqrt{\frac{\alpha_-}{\alpha_+}}\right)^k \|\boldsymbol{\varepsilon}_0 - \boldsymbol{\varepsilon}^*\|_{L^2} -$$ - -where C is a fixed constant, the rate depends on sqrt(alpha_-/alpha_+) giving sqrt(kappa) scaling - -**Heavy ball strain update:** - -$$ -\boldsymbol{\varepsilon}_{k+1} = \bar{\boldsymbol{\varepsilon}} - s_k \boldsymbol{\Gamma} \colon \left( \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_k) - \frac{1}{s_k} \boldsymbol{\varepsilon}_k \right) + \beta_k (\boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1}) -$$ - -where Gradient evaluated at current iterate epsilon_k, momentum added to update - -**Heavy ball optimal parameters:** - -$$ -\frac{1}{s_k} = \left(\frac{\sqrt{\alpha_-} + \sqrt{\alpha_+}}{2}\right)^2, \quad \beta_k = \left(\frac{\sqrt{\alpha_+} - \sqrt{\alpha_-}}{\sqrt{\alpha_+} + \sqrt{\alpha_-}}\right)^2 -$$ - -where Optimal for linear elasticity and potential-based stress operators - -**Notation:** - -- $\mathbf{e}_k$ — Extrapolated point (Nesterov variant) -- $\boldsymbol{\varepsilon}_k$ — Strain field at iteration k -- $\beta_k$ — Momentum parameter -- $s_k$ — Algorithmic step size -- $\alpha_+$ — Lipschitz constant of the stress operator -- $\alpha_-$ — Strong convexity (monotonicity) constant -- $\boldsymbol{\Gamma}$ — Non-dimensional Green's operator -- $\kappa$ — Condition number alpha_+/alpha_- - - -## 3. Algorithmic Implementation -**Algorithm: Nesterov Fast Gradient Method** - -$$ -\begin{algorithmic} -\State $\boldsymbol{\varepsilon}_0(\mathbf{x}) \leftarrow \bar{\boldsymbol{\varepsilon}}, \quad \boldsymbol{\varepsilon}_{-1} \leftarrow \boldsymbol{\varepsilon}_0$ -\State $s \leftarrow 1/\alpha_+, \quad \beta \leftarrow (\sqrt{\alpha_+} - \sqrt{\alpha_-})/(\sqrt{\alpha_+} + \sqrt{\alpha_-})$ -\For{$k = 0, 1, 2, \ldots$} - \State $\mathbf{e}_k \leftarrow \boldsymbol{\varepsilon}_k + \beta (\boldsymbol{\varepsilon}_k - \boldsymbol{\varepsilon}_{k-1})$ - \State $\boldsymbol{\sigma}_k \leftarrow \boldsymbol{\sigma}(\mathbf{e}_k)$ - \State $\boldsymbol{\tau}_k \leftarrow \boldsymbol{\sigma}_k - \frac{1}{s} \mathbf{e}_k$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\boldsymbol{\xi}) \leftarrow -s \, \hat{\boldsymbol{\Gamma}}(\boldsymbol{\xi}) \colon \widehat{\boldsymbol{\tau}}_k(\boldsymbol{\xi}) \quad \forall \boldsymbol{\xi} \neq \mathbf{0}$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\mathbf{0}) \leftarrow \bar{\boldsymbol{\varepsilon}}$ - \State $\boldsymbol{\varepsilon}_{k+1} \leftarrow \text{DFT}^{-1}(\hat{\boldsymbol{\varepsilon}}_{k+1})$ - \If{$\|\boldsymbol{\Gamma} \colon \boldsymbol{\sigma}(\boldsymbol{\varepsilon}_{k+1})\|_{L^2} / \|\langle \boldsymbol{\sigma}_{k+1} \rangle\| < \text{tol}$} - \State \textbf{break} - \EndIf -\EndFor -\end{algorithmic} -$$ - -**Taichi Mapping:** -Extrapolation e_k = epsilon_k + beta*(epsilon_k - epsilon_{k-1}) is a pointwise Taichi kernel requiring both current and previous strain fields (2-field footprint). Stress evaluation at the extrapolated point and FFT operations are identical to the basic scheme. Restart logic (speed restart or Fercoq-Qu) adds a conditional branch resetting beta to zero when the residual increases. - - -## 4. Known Pitfalls -**Sensitive parameter selection:** The optimal parameters $s_k$ and $\beta_k$ require knowledge of the Lipschitz constant $\alpha_+$ and strong convexity constant $\alpha_-$. For nonlinear materials, these bounds may be strain-dependent and difficult to estimate a priori. For porous materials, the effective strong convexity constant is unknown and determining it can be more difficult than solving the problem itself. - - -**Restart strategies add overhead:** Adaptive restart strategies (speed restart by Su et al., Fercoq-Qu restart) are needed to handle unknown material parameters, but they increase the iteration count by a factor of 2-3 compared to the optimal fixed-parameter choice in the linear case. This makes Nesterov's method lag behind BB and nonlinear CG in practice. - - -**Heavy ball method requires potential-based stress:** The heavy ball variant with optimal parameters is only valid when the stress operator derives from a potential (symmetric positive definite tangent). For general monotone but non-symmetric operators, only Nesterov's method provides convergence guarantees. Using heavy ball parameters on non-potential operators can cause divergence. - - -**Instability near sharp contrasts:** The momentum term amplifies oscillations near material interfaces with sharp stiffness jumps. In the presence of high contrast or geometric singularities, the extrapolated point $\mathbf{e}_k$ can overshoot into physically unreasonable strain states, particularly for finite strain formulations. - - -**Inferior to CG and BB in FFT benchmarks:** Despite achieving the theoretically optimal $\sqrt{\kappa}$ rate, Nesterov's method with restart consistently requires 2-3 times more iterations than linear CG, Fletcher-Reeves nonlinear CG, BB, and L-BFGS of depth four in published FFT benchmarks. The constant factor in the convergence estimate is larger than for these competing methods. - - -## 5. References -- Schneider (2021) -- review of nonlinear FFT-based computational homogenization, fast gradient methods (Nesterov and heavy ball) -- Lucarini et al. (2022) -- Nesterov's method and momentum-based acceleration for FFT homogenization - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-krylov-cg.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-krylov-cg.md deleted file mode 100644 index 883d074..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-krylov-cg.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -id: fft-solver-krylov-cg -title: Conjugate Gradient for FFT Homogenization -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- krylov-solver -- conjugate-gradient -- fft-galerkin -- convergence -- iterative -- preconditioning -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: CG solves the Lippmann-Schwinger equation as a linear system -- to: fft-green-operator - type: requires - weight: 0.9 - note: Green's operator application is the dominant cost per CG iteration -- to: fft-reference-medium - type: requires - weight: 0.8 - note: L-S formulation acts as preconditioning by the reference medium -- to: fft-solver-basic-scheme - type: refines - weight: 0.9 - note: CG achieves sqrt(kappa) convergence vs linear kappa for basic scheme -- to: fft-solver-nonlinear-cg - type: feeds-into - weight: 0.8 - note: Linear CG is a special case of nonlinear CG with exact line search -- to: fft-solver-newton-krylov - type: feeds-into - weight: 1.0 - note: CG is used as the inner linear solver in Newton-CG -- to: fft-solver-krylov-minres - type: refines - weight: 0.7 - note: MINRES is the alternative Krylov solver for indefinite symmetric systems -context_size: medium -reading_priority: full -load_with: -- fft-lippmann-schwinger -- fft-green-operator -- fft-reference-medium -content_ref: null -akms_schema: v2 ---- - -# Conjugate Gradient for FFT Homogenization - -## Summary -The Conjugate Gradient (CG) method is a Krylov subspace solver applied to the Lippmann-Schwinger equation of FFT-based homogenization. CG iteratively selects a solution from expanding Krylov subspaces by minimizing a quadratic energy functional $\phi_{A,b}(\mathbf{x}) = \frac{1}{2}\mathbf{x}^T A \mathbf{x} - \mathbf{b}^T \mathbf{x}$. Although the strain-based L-S operator $\mathbf{Id} + \boldsymbol{\Gamma}^0 \colon (\mathbf{C} - \mathbf{C}^0)$ appears non-symmetric on $L^2$, it is symmetric and positive definite on the subspace of compatible strain fields, justifying CG. The key advantage over fixed-point schemes is convergence scaling with $\sqrt{\kappa}$ instead of $\kappa$ (where $\kappa$ is the phase contrast), with iteration count independent of mesh size. The L-S formulation itself serves as preconditioning by the reference medium operator $P = -\mathrm{div}\,\mathbf{C}^0 \nabla^s$, removing mesh-size dependence from the condition number. CG requires storing 4 strain fields and extends to nonlinear problems via the Fletcher-Reeves nonlinear CG formulation. - - -## 1. Core Concept -The CG method solves the strain-based Lippmann-Schwinger equation $(\mathbf{Id} + \boldsymbol{\Gamma}^0 \colon (\mathbf{C}(\mathbf{x}) - \mathbf{C}^0)) \colon \boldsymbol{\varepsilon}(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}}$ as a symmetric positive definite linear system. Each CG iteration requires one application of the Green's operator (via FFT) and one constitutive law evaluation, making it computationally equivalent in cost-per-iteration to the basic scheme. The L-S equation can be interpreted as a preconditioned balance of linear momentum: the preconditioner $P = -\mathrm{div}\,\mathbf{C}^0 \nabla^s$ with inverse $P^{-1} = -\mathbf{G}^0$ removes mesh-size dependence from the condition number but retains dependence on the material contrast. The symmetry and positive definiteness hold on the restricted subspace of compatible strain fields, as shown by $\int_Y \boldsymbol{\varepsilon}_1 \colon \mathbf{C}^0 \colon ((\mathbf{Id} + \boldsymbol{\Gamma}^0 \colon (\mathbf{C} - \mathbf{C}^0)) \colon \boldsymbol{\varepsilon}_2)\,dx = \int_Y \boldsymbol{\varepsilon}_1 \colon \mathbf{C} \colon \boldsymbol{\varepsilon}_2\,dx$ for all compatible $\boldsymbol{\varepsilon}_i = \nabla^s \mathbf{u}_i$. Alternatively, the displacement-based FFT (DBFFT) method solves directly for $\hat{\tilde{\mathbf{u}}}$ in Fourier space with an explicit preconditioner $\mathbf{M}(\boldsymbol{\xi}) = [\boldsymbol{\xi} \cdot \mathbf{C} \cdot \boldsymbol{\xi}]^{-1}$. - - -## 2. Mathematical Formulation -The CG method operates on two equivalent formulations of the linear homogenization problem. In the strain-based form, the unknown is the strain field and the operator is the L-S operator preconditioned by the reference medium. In the displacement-based form (DBFFT), the unknown is the fluctuating displacement in Fourier space and the system is Hermitian. The Krylov subspace framework selects iterates that optimally minimize the energy functional over expanding subspaces. - - -**Strain-based Lippmann-Schwinger system:** - -$$ -(\mathbf{Id} + \boldsymbol{\Gamma}^0 \colon (\mathbf{C}(\mathbf{x}) - \mathbf{C}^0)) \colon \boldsymbol{\varepsilon}(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}} -$$ - -where Gamma0 is the Green's operator, C is the local stiffness, C0 is the reference stiffness - -**CG energy functional (objective):** - -$$ -\phi_{A,b}(\mathbf{x}) = \frac{1}{2}\mathbf{x}^T A \mathbf{x} - \mathbf{b}^T \mathbf{x} -$$ - -where A is the symmetric positive definite L-S operator restricted to compatible fields, b = eps_bar - -**Krylov subspace:** - -$$ -\mathcal{K}_k(A;\mathbf{b}) = \left\{ \sum_{j=0}^{k-1} \alpha_j A^j \mathbf{b} \right\} -$$ - -where k is the iteration number, the CG iterate x_k minimizes phi over K_{k+1} - -**Symmetry on compatible fields:** - -$$ -\int_Y \boldsymbol{\varepsilon}_1 \colon \mathbf{C}^0 \colon ((\mathbf{Id} + \boldsymbol{\Gamma}^0 \colon (\mathbf{C} - \mathbf{C}^0)) \colon \boldsymbol{\varepsilon}_2)\,dx = \int_Y \boldsymbol{\varepsilon}_1(\mathbf{x}) \colon \mathbf{C}(\mathbf{x}) \colon \boldsymbol{\varepsilon}_2(\mathbf{x})\,dx -$$ - -where Holds for all compatible eps_i = grad^s u_i with u_i in H1_per(Y) - -**Search direction update (nonlinear CG / Fletcher-Reeves):** - -$$ -\mathbf{d}_k = -\nabla W(\mathbf{u}_k) + \gamma_{k-1} \mathbf{d}_{k-1} -$$ - -where d_k is the search direction, nabla W is the energy gradient - -**Displacement update:** - -$$ -\mathbf{u}_{k+1} = \mathbf{u}_k + s_k \mathbf{d}_k -$$ - -where s_k is the step size, for linear problems s_k is computed via exact line search - -**Fletcher-Reeves conjugate parameter:** - -$$ -\gamma_{k-1} = \frac{\|\nabla W(\mathbf{u}_k)\|^2}{\|\nabla W(\mathbf{u}_{k-1})\|^2} -$$ - -where Ratio of squared gradient norms; reduces to linear CG for linear elastic problems with exact line search - -**DBFFT preconditioner:** - -$$ -\mathbf{M}(\boldsymbol{\xi}) = [\boldsymbol{\xi} \cdot \mathbf{C} \cdot \boldsymbol{\xi}]^{-1} \quad \text{for } \boldsymbol{\xi} \neq \mathbf{0} -$$ - -where Left preconditioner for the displacement-based FFT system evaluated at each frequency - -**Convergence rate bound:** - -$$ -N_{\text{iter}} \sim \sqrt{\kappa}, \quad \kappa = \alpha_+ / \alpha_- -$$ - -where kappa is the material contrast; basic scheme scales as kappa (linear) - -**Notation:** - -- $\boldsymbol{\Gamma}^0$ — Green's operator for the reference medium -- $\mathbf{C}^0$ — Reference medium stiffness tensor -- $\mathbf{C}(\mathbf{x})$ — Local material stiffness at position x -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain -- $\kappa$ — Phase contrast ratio alpha_+/alpha_- -- $\nabla W$ — Gradient of the stored energy functional -- $\gamma_{k-1}$ — Conjugate parameter (Fletcher-Reeves formula) -- $s_k$ — Step size parameter - - -## 3. Algorithmic Implementation -**Algorithm: Conjugate Gradient for Strain-Based L-S Equation** - -$$ -\begin{algorithmic} -\State $Initialize \colon \boldsymbol{\varepsilon}_0 = \bar{\boldsymbol{\varepsilon}}, \; \mathbf{r}_0 = \bar{\boldsymbol{\varepsilon}} - (\mathbf{Id} + \boldsymbol{\Gamma}^0 \colon (\mathbf{C} - \mathbf{C}^0)) \colon \boldsymbol{\varepsilon}_0, \; \mathbf{d}_0 = \mathbf{r}_0$ -\While{$\|\mathbf{r}_k\| / \|\bar{\boldsymbol{\varepsilon}}\| > \text{tol}$} - \State $\mathbf{q}_k = (\mathbf{Id} + \boldsymbol{\Gamma}^0 \colon (\mathbf{C} - \mathbf{C}^0)) \colon \mathbf{d}_k$ - \State $\alpha_k = \langle \mathbf{r}_k, \mathbf{r}_k \rangle / \langle \mathbf{d}_k, \mathbf{q}_k \rangle$ - \State $\boldsymbol{\varepsilon}_{k+1} = \boldsymbol{\varepsilon}_k + \alpha_k \mathbf{d}_k$ - \State $\mathbf{r}_{k+1} = \mathbf{r}_k - \alpha_k \mathbf{q}_k$ - \State $\beta_k = \langle \mathbf{r}_{k+1}, \mathbf{r}_{k+1} \rangle / \langle \mathbf{r}_k, \mathbf{r}_k \rangle$ - \State $\mathbf{d}_{k+1} = \mathbf{r}_{k+1} + \beta_k \mathbf{d}_k$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -Each CG iteration maps to two Taichi kernels: (1) a real-space kernel for constitutive evaluation (C - C0) : eps at each voxel, (2) a spectral kernel applying Gamma0 via batched FFT. Inner products are parallel reductions. All 4 strain fields (eps, r, d, q) stored as Taichi fields on GPU. - -**Algorithm: Nonlinear CG (Fletcher-Reeves) for FFT Homogenization** - -$$ -\begin{algorithmic} -\State $Initialize \colon \mathbf{u}_0 = \mathbf{0}, \; \nabla W_0 = \boldsymbol{\Gamma} \colon \boldsymbol{\sigma}(\bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_0), \; \mathbf{d}_0 = -\nabla W_0$ -\While{$\|\nabla W(\mathbf{u}_k)\| > \text{tol}$} - \State $\mathbf{u}_{k+1} = \mathbf{u}_k + s_k \mathbf{d}_k, \quad s_k = (\alpha_+ + \alpha_-)/2$ - \State $\nabla W_{k+1} = \boldsymbol{\Gamma} \colon \boldsymbol{\sigma}(\bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_{k+1})$ - \State $\gamma_k = \|\nabla W_{k+1}\|^2 / \|\nabla W_k\|^2$ - \State $\mathbf{d}_{k+1} = -\nabla W_{k+1} + \gamma_k \mathbf{d}_k$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -Same kernel structure as linear CG but with nonlinear constitutive evaluation. Requires only 3 displacement/strain fields. The fixed step size s_k eliminates inner loops. Parallel norm reductions for conjugate parameter computation. - - -## 4. Known Pitfalls -**Failure for infinite contrast (voids/rigid inclusions):** The L-S linear system becomes ill-posed for infinite phase contrast ($\kappa \to \infty$), causing CG to fail to converge. For porous materials, the condition number diverges because the basic scheme attempts a $\mathbf{C}^0$-elastic extension into void space, which is incompatible with trigonometric polynomial discretizations. Discrete (finite difference) discretizations like Willot's scheme are required to handle voids stably. - - -**Hidden symmetry requires compatible strain subspace:** The strain-based L-S operator is NOT symmetric on the full $L^2(Y;\mathrm{Sym}(d))$ space. It is only symmetric and positive definite when restricted to compatible strain fields $\boldsymbol{\varepsilon} = \nabla^s \mathbf{u}$. Despite this, CG converges identically to BiCGStab (a non-symmetric solver) because the CG iterates automatically remain in the compatible subspace. This was a surprising empirical finding by Zeman et al. explained theoretically by Vondrejc et al. - - -**Memory cost in Newton-CG context:** Standalone linear CG requires only 4 strain fields. However, when used as the inner solver in Newton-CG, total memory explodes to 8.5 strain fields plus the tangent stiffness (21 GB for symmetric tangent at $512^3$ voxels). For a $512^3$ grid, Newton-CG requires approximately 51 GB total vs. 6 GB for the basic scheme. - - -**Nonlinear CG step size is fixed, not optimal:** The nonlinear CG extension uses a fixed step size $s_k = (\alpha_+ + \alpha_-)/2$ to avoid expensive line searches (each line search step requires a full constitutive law evaluation). This is only optimal for linear problems; for nonlinear materials with strain-dependent moduli, the fixed step size may lead to slower convergence compared to methods with adaptive step sizes. - - -**Discretization affects convergence behavior:** CG convergence is sensitive to the choice of spatial discretization. The Moulinec-Suquet (trigonometric polynomial) discretization causes CG residual stagnation for porous materials. Willot's finite-difference discretization, staggered grids, and higher-order central differences all yield different convergence profiles for the same microstructure. - - -## 5. References -- Schneider (2021) -- Krylov subspace methods, CG for L-S equation, nonlinear CG with Fletcher-Reeves -- Lucarini et al. (2022) -- Krylov solver algorithm, DBFFT preconditioner, finite strain extensions -- Zeman et al. (2010) -- First application of CG to strain-based L-S equation -- Vondrejc et al. (2012) -- Proof of symmetry on compatible strain subspace -- Brisard and Dormieux (2010) -- CG for polarization-based L-S, preconditioning interpretation - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-krylov-minres.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-krylov-minres.md deleted file mode 100644 index 2cac59c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-krylov-minres.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -id: fft-solver-krylov-minres -title: MINRES for Symmetric FFT Systems -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- krylov-solver -- fft-galerkin -- convergence -- iterative -- preconditioning -- polarization -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: MINRES solves the polarization-based L-S equation -- to: fft-green-operator - type: requires - weight: 0.9 - note: Green's operator Gamma0 appears in the polarization L-S system -- to: fft-reference-medium - type: requires - weight: 1.0 - note: Definiteness of (C - C0)^{-1} + Gamma0 depends critically on C0 choice -- to: fft-solver-krylov-cg - type: refines - weight: 0.9 - note: CG is preferred when the polarization operator is definite; MINRES handles indefinite case -- to: fft-solver-basic-scheme - type: refines - weight: 0.8 - note: MINRES achieves sqrt(kappa) convergence vs linear kappa for basic scheme -context_size: medium -reading_priority: full -load_with: -- fft-solver-krylov-cg -- fft-lippmann-schwinger -- fft-reference-medium -content_ref: null -akms_schema: v2 ---- - -# MINRES for Symmetric FFT Systems - -## Summary -The Minimum Residual method (MINRES) is a Krylov subspace solver for symmetric but potentially indefinite linear systems. In FFT-based homogenization, MINRES is applied to the polarization-based Lippmann-Schwinger equation $(\mathbf{C} - \mathbf{C}^0)^{-1} \colon \boldsymbol{\tau} + \boldsymbol{\Gamma}^0 \colon \boldsymbol{\tau} = \bar{\boldsymbol{\varepsilon}}$, where the operator $(\mathbf{C} - \mathbf{C}^0)^{-1} + \boldsymbol{\Gamma}^0$ is symmetric and invertible but not necessarily positive definite. MINRES minimizes the residual norm $\|A\mathbf{x} - \mathbf{b}\|^2$ over the Krylov subspace, in contrast to CG which minimizes the energy functional. MINRES is required when the reference medium $\mathbf{C}^0$ is neither uniformly softer nor uniformly stiffer than all material phases, making the operator indefinite. The method requires 7 strain fields in memory (vs. 4 for CG), and is restricted to linear problems with no direct nonlinear extension. It has also been applied to indefinite coupled multi-physics problems (e.g., piezoelectrics) and lattice microstructures with large void fractions. - - -## 1. Core Concept -MINRES solves the polarization-based Lippmann-Schwinger equation proposed by Brisard and Dormieux. The unknown is the stress polarization field $\boldsymbol{\tau} = (\mathbf{C} - \mathbf{C}^0) \colon \boldsymbol{\varepsilon}$, and the linear operator $(\mathbf{C} - \mathbf{C}^0)^{-1} + \boldsymbol{\Gamma}^0$ is inherently symmetric on the entire space of voxel-wise constant polarization fields (unlike the strain-based operator which is only symmetric on compatible fields). The definiteness of this operator depends on the reference medium choice: if $\mathbf{C}^0$ is softer than all phases, the operator is positive definite (use CG); if $\mathbf{C}^0$ is stiffer than all phases, it is negative definite (use CG on $-A$); for intermediate $\mathbf{C}^0$, the operator is indefinite and MINRES must be used. The convergence rate scales as $\sqrt{\kappa}$ and is independent of mesh size, matching CG. However, MINRES requires 7 vector fields in memory and cannot be extended to nonlinear constitutive problems. - - -## 2. Mathematical Formulation -The polarization-based formulation converts the cell problem into a symmetric system for the stress polarization. The operator combines the local compliance deviation $(C - C_0)^{-1}$ with the Green's operator, yielding a system that is always symmetric but whose definiteness depends on the reference medium. MINRES minimizes the $L^2$-norm of the residual at each step, making it applicable to indefinite systems where CG would fail. - - -**Polarization-based L-S equation:** - -$$ -((\mathbf{C} - \mathbf{C}^0)^{-1} + \boldsymbol{\Gamma}^0) \colon \boldsymbol{\tau} = \bar{\boldsymbol{\varepsilon}} -$$ - -where tau = (C - C0) : eps is the stress polarization, C0 is the reference stiffness - -**MINRES objective (residual minimization):** - -$$ -\phi_{A,b}(\mathbf{x}) = \|A\mathbf{x} - \mathbf{b}\|^2 \longrightarrow \min_{\mathbf{x} \in \mathcal{K}_{k+1}(A;\mathbf{b})} -$$ - -where A = (C - C0)^{-1} + Gamma0, b = eps_bar; minimizes residual norm over the Krylov subspace - -**CG objective for comparison:** - -$$ -\phi_{A,b}(\mathbf{x}) = \frac{1}{2}\mathbf{x}^T A \mathbf{x} - \mathbf{b}^T \mathbf{x} -$$ - -where CG minimizes the energy functional (requires positive definiteness) - -**Positive definite condition (CG applicable):** - -$$ -\mathbf{C}^0 \prec \mathbf{C}(\mathbf{x}) \quad \forall \mathbf{x} \in Y \implies (\mathbf{C} - \mathbf{C}^0)^{-1} + \boldsymbol{\Gamma}^0 \succ 0 -$$ - -where C0 softer than all local phases yields a positive definite operator - -**Indefinite condition (MINRES required):** - -$$ -\exists\, \mathbf{x}_1, \mathbf{x}_2 \in Y \colon \mathbf{C}(\mathbf{x}_1) \prec \mathbf{C}^0 \prec \mathbf{C}(\mathbf{x}_2) \implies (\mathbf{C} - \mathbf{C}^0)^{-1} + \boldsymbol{\Gamma}^0 \text{ indefinite} -$$ - -where Intermediate reference medium makes the operator a saddle-point system - -**Convergence rate:** - -$$ -N_{\text{iter}} \sim \sqrt{\kappa}, \quad \kappa = \alpha_+ / \alpha_- -$$ - -where Same optimal rate as CG; independent of mesh size - -**Hashin-Shtrikman variational principle:** - -$$ -\frac{1}{2}\langle \boldsymbol{\tau}, (\mathbf{C} - \mathbf{C}^0)^{-1} \colon \boldsymbol{\tau} + \boldsymbol{\Gamma}^0 \colon \boldsymbol{\tau} \rangle_{L^2} - \langle \boldsymbol{\tau}, \bar{\boldsymbol{\varepsilon}} \rangle_{L^2} \longrightarrow \min_{\boldsymbol{\tau}} -$$ - -where Strongly convex when C0 is uniformly softer; becomes a saddle point for intermediate C0 - -**Notation:** - -- $\boldsymbol{\tau}$ — Stress polarization field tau = (C - C0) : eps -- $(\mathbf{C} - \mathbf{C}^0)^{-1}$ — Local compliance deviation tensor (requires C - C0 invertible) -- $\boldsymbol{\Gamma}^0$ — Green's operator for the reference medium -- $\mathbf{C}^0$ — Reference medium stiffness tensor -- $\kappa$ — Phase contrast ratio alpha_+/alpha_- -- $\prec, \succ$ — Definiteness ordering on symmetric tensors - - -## 3. Algorithmic Implementation -**Algorithm: MINRES for Polarization-Based L-S Equation** - -$$ -\begin{algorithmic} -\State $Initialize \colon \boldsymbol{\tau}_0 = \mathbf{0}, \; \mathbf{r}_0 = \bar{\boldsymbol{\varepsilon}} - ((\mathbf{C} - \mathbf{C}^0)^{-1} + \boldsymbol{\Gamma}^0) \colon \boldsymbol{\tau}_0$ -\State $Set \; \mathbf{v}_0 = \mathbf{0}, \; \mathbf{v}_1 = \mathbf{r}_0 / \|\mathbf{r}_0\|, \; \beta_1 = \|\mathbf{r}_0\|$ -\State $Set \; \phi_0 = \beta_1, \; c_0 = 1, \; s_0 = 0, \; \mathbf{d}_{-1} = \mathbf{0}, \; \mathbf{d}_0 = \mathbf{0}$ -\While{$|\phi_k| / \|\bar{\boldsymbol{\varepsilon}}\| > \text{tol}$} - \State $\mathbf{w}_k = ((\mathbf{C} - \mathbf{C}^0)^{-1} + \boldsymbol{\Gamma}^0) \colon \mathbf{v}_k$ - \State $\alpha_k = \langle \mathbf{w}_k, \mathbf{v}_k \rangle, \quad \mathbf{w}_k \leftarrow \mathbf{w}_k - \alpha_k \mathbf{v}_k - \beta_k \mathbf{v}_{k-1}$ - \State $\beta_{k+1} = \|\mathbf{w}_k\|, \quad \mathbf{v}_{k+1} = \mathbf{w}_k / \beta_{k+1}$ - \State $\delta_k^{(1)} = c_{k-1} \alpha_k - s_{k-1} \beta_k c_{k-2} \alpha_{k-1}$ - \State $\gamma_k = \sqrt{(\delta_k^{(1)})^2 + \beta_{k+1}^2}$ - \State $c_k = \delta_k^{(1)} / \gamma_k, \quad s_k = \beta_{k+1} / \gamma_k$ - \State $\mathbf{d}_k = \frac{1}{\gamma_k} \left( \mathbf{v}_k - \delta_k^{(0)} \mathbf{d}_{k-2} - \epsilon_k \mathbf{d}_{k-1} \right)$ - \State $\boldsymbol{\tau}_k = \boldsymbol{\tau}_{k-1} + (c_k \phi_{k-1}) \, \mathbf{d}_k$ - \State $\phi_k = -s_k \phi_{k-1}$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -Each MINRES iteration requires one operator application (real-space kernel for (C-C0)^{-1} : tau + FFT/iFFT pair for Gamma0 : tau). The 7 strain fields stored as Taichi fields on GPU are: v_{k-1}, v_k, v_{k+1}, w_k, d_{k-2}, d_{k-1}, tau_k. Givens rotation scalars (c_k, s_k, phi_k, gamma_k, delta, epsilon) are host-side scalars — negligible memory. Memory-bound by the 7-field requirement. - - -## 4. Known Pitfalls -**High memory footprint (7 strain fields):** MINRES requires 7 vector fields in memory, nearly double the 4 fields needed by CG. For large 3D grids ($512^3$ voxels), each strain field occupies ~6 GB, making MINRES demand ~42 GB for strain storage alone. This severely limits the maximum grid resolution achievable on GPU hardware. - - -**Restricted to linear problems:** Unlike CG, which has a natural nonlinear extension via the Fletcher-Reeves nonlinear CG framework, MINRES has no established nonlinear generalization for FFT-based micromechanics. For nonlinear constitutive models, one must either use MINRES as an inner solver within Newton-Raphson or switch to a different solver family entirely. - - -**Singular (C - C0) breaks the formulation:** If $\mathbf{C}^0$ is chosen such that $\mathbf{C}(\mathbf{x}) = \mathbf{C}^0$ for any material phase in the microstructure, the difference $\mathbf{C} - \mathbf{C}^0$ becomes singular and the compliance deviation $(\mathbf{C} - \mathbf{C}^0)^{-1}$ is undefined. This completely breaks the polarization formulation. The reference medium must be chosen so that the difference is invertible everywhere. - - -**Solution depends on reference medium:** Unlike displacement-based discretizations where $\mathbf{C}^0$ is purely a numerical parameter, the Brisard-Dormieux polarization discretization produces solutions $\boldsymbol{\tau}_N$ that depend on the reference medium. A judicious choice of $\mathbf{C}^0$ is required to balance accuracy of the discrete solution and conditioning of the linear system. - - -**Poor conditioning for intermediate C0:** When $\mathbf{C}^0$ is intermediate (neither softer nor stiffer than all phases), the operator becomes indefinite and the system is a saddle-point problem. While MINRES can handle this, the condition number may be worse than in the definite case, leading to more iterations. The optimal $\mathbf{C}^0$ choice for MINRES is not as well-characterized as for CG. - - -## 5. References -- Schneider (2021) -- MINRES for polarization L-S equation, comparison with CG, memory footprint -- Brisard and Dormieux (2010) -- Polarization formulation with CG and MINRES for different C0 choices -- Lucarini et al. (2022) -- MINRES with Fourier-Galerkin and finite-difference frequencies for lattice microstructures - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-newton-krylov.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-newton-krylov.md deleted file mode 100644 index f6cf010..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-newton-krylov.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -id: fft-solver-newton-krylov -title: Newton-Krylov Methods for FFT (Newton-CG/GMRES) -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- newton -- krylov-solver -- conjugate-gradient -- fft-galerkin -- convergence -- iterative -- nonlinear -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 0.9 - note: Linearized equilibrium can be rewritten in L-S form with residual stresses -- to: fft-green-operator - type: requires - weight: 0.9 - note: Green's operator used in the L-S form of the linearized system -- to: fft-reference-medium - type: requires - weight: 0.7 - note: Reference medium appears in the L-S reformulation of the tangent system -- to: fft-solver-krylov-cg - type: requires - weight: 1.0 - note: CG is the standard inner Krylov solver (Newton-CG) -- to: fft-solver-basic-scheme - type: refines - weight: 0.7 - note: Basic scheme can serve as inner solver for the linearized equation -- to: fft-solver-quasi-newton - type: refines - weight: 0.9 - note: Quasi-Newton (L-BFGS, Anderson) are memory-efficient alternatives to Newton-Krylov -- to: fft-solver-nonlinear-cg - type: feeds-into - weight: 0.7 - note: Nonlinear CG avoids tangent storage but converges more slowly -context_size: large -reading_priority: full -load_with: -- fft-solver-krylov-cg -- fft-solver-quasi-newton -- fft-lippmann-schwinger -content_ref: null -akms_schema: v2 ---- - -# Newton-Krylov Methods for FFT (Newton-CG/GMRES) - -## Summary -Newton-Krylov methods couple a Newton-Raphson outer loop for the nonlinear balance equation with an iterative Krylov subspace inner solver for the linearized system. The outer loop updates the displacement field via $\mathbf{u}_{k+1} = \mathbf{u}_k + s_k \delta\mathbf{u}_k$, where the increment $\delta\mathbf{u}_k$ solves the linearized equilibrium equation $\mathrm{div}\,(\frac{\partial^2 w}{\partial\boldsymbol{\varepsilon}^2} \colon \nabla^s \delta\mathbf{u}_k) = -\mathrm{div}\,\frac{\partial w}{\partial\boldsymbol{\varepsilon}}$. The inner linear system is solved iteratively using CG (Newton-CG) or GMRES, making this an inexact Newton method. Newton-CG is the most effective solver combination when the tangent stiffness application is cheaper than the nonlinear constitutive law evaluation. However, it carries massive memory costs: for $512^3$ voxels, Newton-CG requires ~51 GB (21 GB for tangent + 5 strain fields), compared to 6 GB for the basic scheme. Global convergence requires back-tracking line search and a dynamically adjusted forcing term (inner solver tolerance). The method extends to finite strains but loses tangent symmetry, requiring GMRES instead of CG. - - -## 1. Core Concept -Newton-Krylov methods are the standard approach for nonlinear FFT-based homogenization when the material tangent is available and cheap to evaluate. The Newton-Raphson outer loop linearizes the nonlinear balance equation $\mathrm{div}\,\frac{\partial w}{\partial\boldsymbol{\varepsilon}}(\cdot, \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}) = 0$ around the current iterate, producing a linear system involving the tangent stiffness tensor $\frac{\partial^2 w}{\partial\boldsymbol{\varepsilon}^2}$. This linearized system is solved iteratively by a Krylov solver (typically CG for symmetric tangents), making the overall method an inexact Newton method. The key advantage is quadratic convergence of the outer loop near the solution, meaning far fewer nonlinear constitutive evaluations than fixed-point schemes. The linearized system can equivalently be written in Lippmann-Schwinger form with residual stresses: $\delta\boldsymbol{\varepsilon}_k + \boldsymbol{\Gamma}^0 \colon ((\frac{\partial^2 w}{\partial\boldsymbol{\varepsilon}^2} - \mathbf{C}^0) \colon \delta\boldsymbol{\varepsilon}_k + \frac{\partial w}{\partial\boldsymbol{\varepsilon}}) = 0$. - - -## 2. Mathematical Formulation -The Newton-Krylov framework consists of two nested iterations: an outer Newton loop that handles nonlinearity and an inner Krylov loop that solves the linearized system. The tangent stiffness operator at each Newton step defines a linear system whose solution is the displacement increment. The forcing term controls the accuracy of the inner solve and must be adapted to the outer residual to maintain overall convergence. - - -**Nonlinear balance equation:** - -$$ -\mathrm{div}\,\frac{\partial w}{\partial\boldsymbol{\varepsilon}}(\cdot, \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}) = 0 -$$ - -where w is the free energy density, u is the displacement fluctuation - -**Newton update:** - -$$ -\mathbf{u}_{k+1} = \mathbf{u}_k + s_k \delta\mathbf{u}_k -$$ - -where s_k in (0,1] is the step size from line search, delta u_k is the Newton increment - -**Linearized equilibrium (tangent system):** - -$$ -\mathrm{div}\left(\frac{\partial^2 w}{\partial\boldsymbol{\varepsilon}^2}(\cdot, \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_k) \colon \nabla^s \delta\mathbf{u}_k\right) = -\mathrm{div}\,\frac{\partial w}{\partial\boldsymbol{\varepsilon}}(\cdot, \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_k) -$$ - -where The tangent stiffness tensor d^2w/deps^2 is evaluated at the current strain state - -**L-S form of linearized system (with residual stresses):** - -$$ -\delta\boldsymbol{\varepsilon}_k + \boldsymbol{\Gamma}^0 \colon \left[\left(\frac{\partial^2 w}{\partial\boldsymbol{\varepsilon}^2}(\cdot, \boldsymbol{\varepsilon}_k) - \mathbf{C}^0\right) \colon \delta\boldsymbol{\varepsilon}_k + \frac{\partial w}{\partial\boldsymbol{\varepsilon}}(\cdot, \boldsymbol{\varepsilon}_k)\right] = 0 -$$ - -where eps_k = eps_bar + grad^s u_k, delta_eps_k = grad^s delta_u_k - -**Tangent stiffness tensor:** - -$$ -\mathbb{C}_k(\mathbf{x}) = \frac{\partial^2 w}{\partial\boldsymbol{\varepsilon}^2}(\mathbf{x}, \boldsymbol{\varepsilon}_k(\mathbf{x})) -$$ - -where Fourth-order tensor evaluated pointwise at each voxel; symmetric for small-strain potential-based models - -**Memory cost estimate (512^3 voxels, symmetric tangent):** - -$$ -\text{Memory} \approx 21\,\text{GB (tangent)} + 5 \times 6\,\text{GB (strain fields)} = 51\,\text{GB} -$$ - -where A single strain field occupies 6 GB at 512^3 resolution in double precision - -**Notation:** - -- $w$ — Free energy density (stored energy function) -- $\frac{\partial w}{\partial\boldsymbol{\varepsilon}}$ — Stress tensor sigma = dw/deps -- $\frac{\partial^2 w}{\partial\boldsymbol{\varepsilon}^2}$ — Material tangent stiffness (fourth-order tensor) -- $\delta\mathbf{u}_k$ — Newton displacement increment at step k -- $s_k$ — Newton step size from back-tracking line search, s_k in (0,1] -- $\boldsymbol{\Gamma}^0$ — Green's operator for the reference medium - - -## 3. Algorithmic Implementation -**Algorithm: Newton-CG for Nonlinear FFT Homogenization** - -$$ -\begin{algorithmic} -\State $Initialize \colon \mathbf{u}_0 = \mathbf{0}, \; \boldsymbol{\varepsilon}_0 = \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_0$ -\State $Evaluate \; \boldsymbol{\sigma}_0 = \frac{\partial w}{\partial\boldsymbol{\varepsilon}}(\cdot, \boldsymbol{\varepsilon}_0), \quad \mathbb{C}_0 = \frac{\partial^2 w}{\partial\boldsymbol{\varepsilon}^2}(\cdot, \boldsymbol{\varepsilon}_0)$ -\While{$\|\mathrm{div}\,\boldsymbol{\sigma}_k\|_{H^{-1}} > \text{tol}_{\text{outer}}$} - \State $\text{Set forcing term}\colon \eta_k = \min(0.9,\, c \|\mathrm{div}\,\boldsymbol{\sigma}_k\|)$ - \State $\text{Solve (CG)}\colon \delta\boldsymbol{\varepsilon}_k + \boldsymbol{\Gamma}^0 \colon ((\mathbb{C}_k - \mathbf{C}^0) \colon \delta\boldsymbol{\varepsilon}_k + \boldsymbol{\sigma}_k) = 0 \quad \text{to tolerance } \eta_k$ - \State $\text{Line search}\colon s_k = \text{backtrack}(\mathbf{u}_k, \delta\mathbf{u}_k) \in (0, 1]$ - \State $\mathbf{u}_{k+1} = \mathbf{u}_k + s_k \delta\mathbf{u}_k$ - \State $\boldsymbol{\varepsilon}_{k+1} = \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_{k+1}$ - \State $\boldsymbol{\sigma}_{k+1} = \frac{\partial w}{\partial\boldsymbol{\varepsilon}}(\cdot, \boldsymbol{\varepsilon}_{k+1}), \quad \mathbb{C}_{k+1} = \frac{\partial^2 w}{\partial\boldsymbol{\varepsilon}^2}(\cdot, \boldsymbol{\varepsilon}_{k+1})$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -Outer Newton loop on host. Inner CG loop maps to GPU kernels: (1) tangent application C_k : delta_eps at each voxel (embarrassingly parallel), (2) FFT/iFFT pair for Gamma0. Tangent tensor stored as a 6x6 symmetric matrix per voxel in a Taichi field (21 floats/voxel). Back-tracking line search requires additional constitutive evaluations on GPU. Memory-dominated by tangent storage. - - -## 4. Known Pitfalls -**Massive memory cost from tangent storage:** The spatially varying tangent stiffness $\mathbb{C}_k(\mathbf{x})$ must be stored at every voxel. For symmetric tangents (21 independent components) on a $512^3$ grid in double precision, this requires 21 GB. Including the 5 strain fields for CG (30 GB), total memory is ~51 GB. Single-precision tangent and displacement-based implementation can reduce this to ~25 GB, but it remains far above the 6-12 GB of gradient-based solvers. - - -**Not globally convergent without line search:** Pure Newton-Raphson diverges if the initial guess is outside the local region of attraction. A globalization strategy (back-tracking line search) is essential: reduce $s_k$ along the Newton direction until sufficient decrease in the residual or energy is achieved. Without line search, the method may oscillate or diverge for large strain increments or path-dependent materials. - - -**Forcing term must be adaptive:** The inner CG tolerance (forcing term $\eta_k$) must decrease as the outer Newton residual decreases. A fixed tight tolerance wastes inner iterations early when the outer solution is far from converged. A fixed loose tolerance prevents quadratic convergence near the solution. The standard choice is $\eta_k = \min(0.9, c\|\text{residual}_k\|)$ where $c$ is a small constant. - - -**Non-symmetric tangent at finite strains:** At finite strains with the first Piola-Kirchhoff stress and deformation gradient, the material tangent $\partial\mathbf{P}/\partial\mathbf{F}$ is fundamentally non-symmetric. This prevents use of CG for the inner solve (requiring GMRES instead) and forces storage of the full non-symmetric tangent (36 components instead of 21), further increasing memory demands. - - -**Inapplicable to black-box constitutive models:** Newton-Krylov requires explicit access to the tangent stiffness $\partial^2 w / \partial\boldsymbol{\varepsilon}^2$. For black-box material subroutines or models without analytical tangent expressions, the method cannot be used. Alternatives include numerical tangent approximation (expensive, inaccurate), or switching to tangent-free methods like Anderson mixing or nonlinear CG. - - -## 5. References -- Schneider (2021) -- Newton-Krylov methods, forcing term, line search, memory cost analysis -- Kabel et al. (2014) -- Newton-CG as most effective combination for finite strain FFT -- Wicht et al. (2020) -- Forcing term strategy and globalization for FFT Newton solvers -- Lahellec et al. (2003) -- Newton-Raphson with basic scheme as inner solver for finite strains -- Lucarini et al. (2022) -- DBFFT Newton framework, non-symmetric tangent at finite strains - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-nonlinear-cg.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-nonlinear-cg.md deleted file mode 100644 index d181b64..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-nonlinear-cg.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -id: fft-solver-nonlinear-cg -title: Nonlinear Conjugate Gradient for FFT -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- fft-galerkin -- spectral -- convergence -- accelerated-schemes -- iterative -- conjugate-gradient -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-solver-basic-scheme - type: requires - weight: 1.0 - note: Uses the basic scheme's gradient computation and step size formula -- to: fft-lippmann-schwinger - type: requires - weight: 0.9 - note: Gradient is the Green's operator applied to the stress (L-S residual) -- to: fft-green-operator - type: requires - weight: 0.9 - note: Energy gradient computed via Green's operator in Fourier space -- to: fft-reference-medium - type: requires - weight: 0.7 - note: Step size alpha_0 = (alpha_+ + alpha_-)/2 from reference medium theory -- to: fft-solver-barzilai-borwein - type: refines - weight: 0.7 - note: Comparable iteration count in benchmarks; CG uses conjugate directions, BB uses adaptive step -- to: fft-solver-fast-gradient - type: refines - weight: 0.6 - note: CG outperforms Nesterov methods in FFT benchmarks -- to: fft-solver-krylov-cg - type: refines - weight: 0.8 - note: For linear problems with exact line search, nonlinear CG produces identical iterates to linear CG -- to: fft-convergence-schemes - type: feeds-into - weight: 0.7 - note: Among the fastest gradient-based methods for FFT homogenization -context_size: medium -reading_priority: full -load_with: -- fft-solver-basic-scheme -- fft-solver-barzilai-borwein -content_ref: null -akms_schema: v2 ---- - -# Nonlinear Conjugate Gradient for FFT - -## Summary -The nonlinear conjugate gradient (CG) method extends gradient descent for FFT homogenization by building conjugate search directions that accelerate convergence beyond what plain or momentum-augmented gradient methods achieve. The search direction $\mathbf{d}_k$ combines the negative energy gradient with the previous direction scaled by the Fletcher-Reeves coefficient $\gamma_{k-1} = \|\nabla W(\mathbf{u}_k)\|^2 / \|\nabla W(\mathbf{u}_{k-1})\|^2$. To avoid expensive line searches, a fixed step size $\alpha_0 = (\alpha_+ + \alpha_-)/2$ is used. The method can be interpreted as a discrete dynamical system with feedback control. Memory footprint is 3 strain fields with two FFT evaluations per iteration. For linear problems with exact line search, Fletcher-Reeves CG produces identical iterates to the standard linear CG method. It is among the fastest gradient-based FFT solvers, competitive with BB and L-BFGS of depth four. - - -## 1. Core Concept -The nonlinear CG method improves upon gradient descent by maintaining a search direction that incorporates information from previous iterates via the conjugate parameter $\gamma_{k-1}$. At each iteration, the energy gradient $\nabla W(\mathbf{u}_k) = G \, \partial w / \partial \boldsymbol{\varepsilon}(\cdot, \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_k)$ is computed by applying the non-dimensional Green's operator $G$ to the stress field in Fourier space. The search direction $\mathbf{d}_k = -\nabla W(\mathbf{u}_k) + \gamma_{k-1} \mathbf{d}_{k-1}$ combines the steepest descent direction with momentum from the previous search direction. The Fletcher-Reeves formula for $\gamma_{k-1}$ is preferred because it automatically degrades to steepest descent when the gradient changes direction sharply, providing implicit restart behavior. The displacement is updated as $\mathbf{u}_{k+1} = \mathbf{u}_k + s_k \mathbf{d}_k$ with the fixed step size from the optimal gradient scheme. The corresponding strain is recovered via $\boldsymbol{\varepsilon}_k = \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_k$. The method avoids line search entirely, trading the exact conjugacy property for generality and computational efficiency. - - -## 2. Mathematical Formulation -The nonlinear CG method operates on the displacement fluctuation field and minimizes the total condensed elastic energy. The gradient is computed via the Green's operator, the search direction is updated via the Fletcher-Reeves formula, and the displacement is advanced with a fixed step size. The strain-based formulation can be recovered through the kinematic relation. - - -**Energy gradient via Green's operator:** - -$$ -\nabla W(\mathbf{u}_k) = G \frac{\partial w}{\partial \boldsymbol{\varepsilon}}(\cdot, \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_k) -$$ - -where G is the non-dimensional Green's operator, w is the condensed free energy density - -**Fletcher-Reeves conjugate parameter:** - -$$ -\gamma_{k-1} = \frac{\|\nabla W(\mathbf{u}_k)\|^2}{\|\nabla W(\mathbf{u}_{k-1})\|^2} -$$ - -where Ratio of squared gradient norms at consecutive iterations - -**Search direction update:** - -$$ -\mathbf{d}_k = -\nabla W(\mathbf{u}_k) + \gamma_{k-1} \mathbf{d}_{k-1} -$$ - -where d_k combines negative gradient with previous direction; d_0 = -nabla W(u_0) - -**Displacement update:** - -$$ -\mathbf{u}_{k+1} = \mathbf{u}_k + s_k \mathbf{d}_k -$$ - -where s_k is the fixed step size parameter - -**Fixed step size (no line search):** - -$$ -\alpha_0 = \frac{\alpha_+ + \alpha_-}{2} -$$ - -where Identical to the optimal basic scheme reference medium; avoids expensive constitutive evaluations for line search - -**Strain recovery:** - -$$ -\boldsymbol{\varepsilon}_k = \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_k -$$ - -where Symmetrized gradient maps displacement fluctuation to total strain - -**Strain-space gradient (residual):** - -$$ -\boldsymbol{\Gamma} \colon \frac{\partial w}{\partial \boldsymbol{\varepsilon}}(\cdot, \boldsymbol{\varepsilon}_k) -$$ - -where Gamma is the Eshelby-Green operator; this is the L-S residual evaluated in Fourier space - -**Notation:** - -- $\nabla W$ — Gradient of the total condensed elastic energy -- $G$ — Non-dimensional Green's operator for displacement -- $\boldsymbol{\Gamma}$ — Eshelby-Green operator (strain-based) -- $\mathbf{d}_k$ — Search direction at iteration k -- $\gamma_{k-1}$ — Fletcher-Reeves conjugate parameter -- $s_k$ — Fixed step size (= 1/alpha_0) -- $\alpha_+$ — Lipschitz constant of the stress operator -- $\alpha_-$ — Strong convexity constant -- $\mathbf{u}_k$ — Displacement fluctuation field at iteration k -- $\boldsymbol{\varepsilon}_k$ — Strain field at iteration k - - -## 3. Algorithmic Implementation -**Algorithm: Nonlinear Conjugate Gradient (Fletcher-Reeves)** - -$$ -\begin{algorithmic} -\State $\mathbf{u}_0 \leftarrow \mathbf{0}, \quad \boldsymbol{\varepsilon}_0 \leftarrow \bar{\boldsymbol{\varepsilon}}$ -\State $\mathbf{g}_0 \leftarrow G \, \partial w / \partial \boldsymbol{\varepsilon}(\cdot, \boldsymbol{\varepsilon}_0)$ -\State $\mathbf{d}_0 \leftarrow -\mathbf{g}_0$ -\For{$k = 0, 1, 2, \ldots$} - \State $\mathbf{u}_{k+1} \leftarrow \mathbf{u}_k + s_k \mathbf{d}_k$ - \State $\boldsymbol{\varepsilon}_{k+1} \leftarrow \bar{\boldsymbol{\varepsilon}} + \nabla^s \mathbf{u}_{k+1}$ - \State $\mathbf{g}_{k+1} \leftarrow G \, \partial w / \partial \boldsymbol{\varepsilon}(\cdot, \boldsymbol{\varepsilon}_{k+1})$ - \If{$\|\mathbf{g}_{k+1}\| / \|\langle \boldsymbol{\sigma}_{k+1} \rangle\| < \text{tol}$} - \State \textbf{break} - \EndIf - \State $\gamma_k \leftarrow \|\mathbf{g}_{k+1}\|^2 / \|\mathbf{g}_k\|^2$ - \State $\mathbf{d}_{k+1} \leftarrow -\mathbf{g}_{k+1} + \gamma_k \mathbf{d}_k$ -\EndFor -\end{algorithmic} -$$ - -**Taichi Mapping:** -The displacement update and strain recovery are pointwise Taichi kernels. Gradient computation requires one forward FFT (stress to Fourier space), Green's operator application (pointwise in Fourier space), and one inverse FFT. The Fletcher-Reeves coefficient gamma_k requires two global reduction kernels for the gradient norms. Three strain/displacement fields must be stored: current u_k, search direction d_k, and gradient g_k. - - -## 4. Known Pitfalls -**Fixed step size suboptimality:** The fixed step size $\alpha_0 = (\alpha_+ + \alpha_-)/2$ avoids expensive line searches but sacrifices the exact conjugacy that makes linear CG optimal. For strongly nonlinear problems, the fixed step size can lead to suboptimal search directions and slower convergence than what a line search would achieve. The trade-off is justified because each constitutive evaluation in FFT homogenization is expensive. - - -**Loss of conjugacy in nonlinear problems:** Theoretical CG guarantees conjugacy of search directions only for linear problems with exact line search. In the nonlinear FFT setting with fixed step size, conjugacy is progressively lost over iterations. The Fletcher-Reeves formula provides implicit restart when the gradient changes direction sharply (gamma becomes small), partially mitigating this issue. - - -**Higher memory than BB and Nesterov:** Nonlinear CG requires 3 strain fields (current state, search direction, gradient) compared to 2 for BB and Nesterov methods. For large 3D problems with $512^3$ voxels where a single strain field occupies 6 GB, this extra field (18 GB vs 12 GB total) can be significant, though still far less than Newton-CG (51+ GB). - - -**Requires smooth energy landscape:** The Fletcher-Reeves formula assumes a smooth gradient field. For materials with sharp yield surfaces, damage, or phase transformations that create discontinuities in the stress-strain response, the conjugate parameter $\gamma_{k-1}$ can become unreliable. In such cases, the method may need frequent explicit restarts or a switch to a more robust solver like BB. - - -**Parameter estimation still needed:** Although the method avoids line search, it still requires estimates of $\alpha_+$ and $\alpha_-$ for the fixed step size. For nonlinear materials, these bounds may be unknown or strain-dependent. Unlike BB which is fully parameter-free, nonlinear CG inherits the reference medium sensitivity of the basic scheme for the step size selection. - - -## 5. References -- Schneider (2021) -- review of nonlinear FFT-based computational homogenization, nonlinear conjugate gradient with Fletcher-Reeves formula -- Lucarini et al. (2022) -- non-linear conjugate gradient approaches for FFT homogenization - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-polarization-admm.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-polarization-admm.md deleted file mode 100644 index 3e94b82..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-polarization-admm.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -id: fft-solver-polarization-admm -title: Polarization Methods & ADMM for FFT -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- polarization -- fft-galerkin -- convergence -- accelerated-schemes -- iterative -- operator-splitting -- admm -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 1.0 - note: ADMM reformulates the Lippmann-Schwinger problem as constrained optimization with augmented Lagrangian -- to: fft-green-operator - type: requires - weight: 1.0 - note: Strain update uses the Green's operator Gamma^0 in Fourier space -- to: fft-reference-medium - type: requires - weight: 0.9 - note: Reference stiffness C^0 = alpha_0 Id controls the augmented Lagrangian penalty -- to: fft-solver-basic-scheme - type: requires - weight: 0.7 - note: ADMM strain update has the same structure as the basic scheme applied to a modified right-hand side -- to: fft-solver-eyre-milton - type: refines - weight: 0.9 - note: ADMM is Douglas-Rachford (gamma=1/2); Eyre-Milton is Peaceman-Rachford (gamma=0) in the unified framework -- to: fft-convergence-schemes - type: feeds-into - weight: 0.7 - note: ADMM convergence and comparison with other solver families -- to: fft-galerkin-basics - type: requires - weight: 0.6 - note: Variational formulation underlying the augmented Lagrangian -context_size: medium -reading_priority: full -load_with: -- fft-solver-eyre-milton -- fft-reference-medium -- fft-green-operator -content_ref: null -akms_schema: v2 ---- - -# Polarization Methods & ADMM for FFT - -## Summary -The ADMM (Alternating Direction Method of Multipliers) approach to FFT homogenization reformulates the unconstrained variational problem as a constrained optimization by introducing an auxiliary strain field $\mathbf{e}$ tied to the compatible strain $\boldsymbol{\varepsilon}$ via a Lagrange multiplier $\lambda$. The augmented Lagrangian functional adds a quadratic penalty scaled by the reference stiffness $\alpha_0$. The three-step iteration alternates between a global strain update (FFT-based Green's operator application), a local nonlinear auxiliary strain update (proximal operator), and a Lagrange multiplier update. The scheme is mathematically equivalent to Douglas-Rachford splitting and corresponds to the damping parameter $\gamma = 1/2$ in the generalized Monchiet-Bonnet framework. It converges for any reference material and any initial iterate, requiring 3 fields in memory. The un-damped variant ($\gamma = 0$) recovers the Eyre-Milton scheme with faster convergence. - - -## 1. Core Concept -The variational problem $\min_u \int_Y w(\mathbf{x}, \bar{\varepsilon} + \nabla^s \mathbf{u}) \, d\mathbf{x}$ is converted to a constrained problem by introducing an auxiliary strain $\mathbf{e}$ subject to $\varepsilon = \mathbf{e}$, then solved via the augmented Lagrangian $L_{\alpha_0}(\mathbf{u}, \mathbf{e}, \lambda)$. The ADMM approach finds saddle points by alternating partial minimizations. The strain update minimizes $L$ over compatible fields (global, FFT-based); the auxiliary update minimizes $L$ over $\mathbf{e}$ pointwise (local, nonlinear); and the multiplier update enforces the constraint. This three-field splitting isolates the nonlinear constitutive evaluation into a purely local proximal operator, avoiding global tangent matrices. The generalized framework with damping parameter $\gamma \in [0,1)$ unifies Douglas-Rachford ($\gamma = 1/2$) and Peaceman-Rachford ($\gamma = 0$), with all variants converging linearly. - - -## 2. Mathematical Formulation -The augmented Lagrangian combines the free energy evaluated on the auxiliary strain, the constraint enforcement via the Lagrange multiplier, and a quadratic penalty. The ADMM iteration splits into three sub-problems that decouple the global compatibility projection from the local constitutive evaluation. The generalized framework introduces an intermediate strain that interpolates between ADMM and Eyre-Milton behavior. - - -**Augmented Lagrangian functional:** - -$$ -L_{\alpha_0}(\mathbf{u}, \mathbf{e}, \lambda) = \int_Y w(\mathbf{x}, \mathbf{e}) + \lambda \colon (\bar{\varepsilon} + \nabla^s \mathbf{u} - \mathbf{e}) + \alpha_0 \|\bar{\varepsilon} + \nabla^s \mathbf{u} - \mathbf{e}\|^2 \, d\mathbf{x} -$$ - -where w is the condensed free energy, lambda is the Lagrange multiplier, alpha_0 is the penalty parameter - -**ADMM strain update (global, FFT-based):** - -$$ -\boldsymbol{\varepsilon}_{k+1} = \bar{\boldsymbol{\varepsilon}} - \boldsymbol{\Gamma}^0 \colon (\lambda_k - \mathbf{C}^0 \colon \mathbf{e}_k) -$$ - -where Gamma^0 is the Green's operator; this projects onto compatible strain fields - -**ADMM auxiliary strain update (local, nonlinear):** - -$$ -\mathbf{e}_{k+1} = \left(\frac{\partial w}{\partial \varepsilon} + \mathbf{C}^0\right)^{-1}(\lambda_k + \mathbf{C}^0 \colon \boldsymbol{\varepsilon}_{k+1}) -$$ - -where Local nonlinear solve (proximal operator) at each grid point - -**ADMM Lagrange multiplier update:** - -$$ -\lambda_{k+1} = \lambda_k + \mathbf{C}^0 \colon (\boldsymbol{\varepsilon}_{k+1} - \mathbf{e}_{k+1}) -$$ - -where lambda converges to the true stress field sigma = dw/depsilon at the solution - -**Generalized framework with damping (Monchiet-Bonnet):** - -$$ -\boldsymbol{\varepsilon}^{k+1/2} = \bar{\varepsilon} - \Gamma^0 \colon (\lambda^k - \mathbf{C}^0 \colon \mathbf{e}^k), \quad \boldsymbol{\varepsilon}^{k+1} = 2(1-\gamma)\boldsymbol{\varepsilon}^{k+1/2} - (1-2\gamma)\mathbf{e}^k -$$ - -where gamma = 1/2 gives ADMM (Douglas-Rachford), gamma = 0 gives Eyre-Milton (Peaceman-Rachford) - -**Douglas-Rachford equivalence:** - -$$ -\gamma = \tfrac{1}{2} \implies \boldsymbol{\varepsilon}^{k+1} = \boldsymbol{\varepsilon}^{k+1/2} \quad \text{(standard ADMM)} -$$ - -where With gamma = 1/2 the intermediate and final strain coincide - -**Notation:** - -- $L_{\alpha_0}$ — Augmented Lagrangian functional -- $\mathbf{e}_k$ — Auxiliary strain field at iteration k -- $\lambda_k$ — Lagrange multiplier (converges to stress at solution) -- $\boldsymbol{\varepsilon}_k$ — Compatible strain field at iteration k -- $\mathbf{C}^0$ — Reference medium stiffness tensor (C^0 = alpha_0 Id) -- $\boldsymbol{\Gamma}^0$ — Green's operator of the reference medium -- $\gamma$ — Damping parameter in the generalized framework -- $\alpha_0$ — Scalar reference stiffness / penalty parameter - - -## 3. Algorithmic Implementation -**Algorithm: ADMM Polarization Scheme (Douglas-Rachford)** - -$$ -\begin{algorithmic} -\State $\boldsymbol{\varepsilon}_0(\mathbf{x}) \leftarrow \bar{\boldsymbol{\varepsilon}}, \quad \mathbf{e}_0(\mathbf{x}) \leftarrow \bar{\boldsymbol{\varepsilon}}, \quad \lambda_0(\mathbf{x}) \leftarrow \mathbb{C}(\mathbf{x}) \colon \bar{\boldsymbol{\varepsilon}}$ -\While{$\|\boldsymbol{\varepsilon}_{k+1} - \mathbf{e}_{k+1}\|_{L^2} / \|\boldsymbol{\varepsilon}\| > \text{tol} \;\text{ or }\; \|\mathbb{C}(\mathbf{x}) \colon \boldsymbol{\varepsilon}_{k+1} - \lambda_{k+1}\|_{L^2} / \|\mathbf{C}^0 \colon \boldsymbol{\varepsilon}\| > \text{tol}$} - \State $\hat{\boldsymbol{r}}_k \leftarrow \text{DFT}(\lambda_k - \mathbf{C}^0 \colon \mathbf{e}_k)$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\boldsymbol{\xi}) \leftarrow -\hat{\boldsymbol{\Gamma}}^0(\boldsymbol{\xi}) \colon \hat{\boldsymbol{r}}_k(\boldsymbol{\xi}) \quad \forall \boldsymbol{\xi} \neq \mathbf{0}$ - \State $\hat{\boldsymbol{\varepsilon}}_{k+1}(\mathbf{0}) \leftarrow \bar{\boldsymbol{\varepsilon}}$ - \State $\boldsymbol{\varepsilon}_{k+1} \leftarrow \text{DFT}^{-1}(\hat{\boldsymbol{\varepsilon}}_{k+1})$ - \State $\mathbf{e}_{k+1}(\mathbf{x}) \leftarrow \left(\frac{\partial w}{\partial \varepsilon}(\mathbf{x}, \cdot) + \mathbf{C}^0\right)^{-1}\!\bigl(\lambda_k(\mathbf{x}) + \mathbf{C}^0 \colon \boldsymbol{\varepsilon}_{k+1}(\mathbf{x})\bigr) \quad \text{(local solve)}$ - \State $\lambda_{k+1}(\mathbf{x}) \leftarrow \lambda_k(\mathbf{x}) + \mathbf{C}^0 \colon \bigl(\boldsymbol{\varepsilon}_{k+1}(\mathbf{x}) - \mathbf{e}_{k+1}(\mathbf{x})\bigr)$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -The strain update decomposes into forward FFT, pointwise Green's operator kernel in Fourier space, and inverse FFT. The auxiliary strain update (local nonlinear solve) and Lagrange multiplier update are purely pointwise Taichi kernels over the voxel grid. Convergence checks require two parallel reductions for the compatibility and constitutive norms. Memory footprint is 3 symmetric tensor fields (strain, auxiliary strain, Lagrange multiplier). - - -## 4. Known Pitfalls -**Intermediate iterates are neither compatible nor in equilibrium:** Unlike gradient-based solvers where the strain iterate is always compatible, ADMM iterates split compatibility and constitutive consistency across separate fields. The auxiliary strain $\mathbf{e}$ satisfies the constitutive law but is not compatible, while $\varepsilon$ is compatible but does not satisfy the constitutive law until convergence. This requires dual convergence criteria (compatibility and constitutive) rather than a single equilibrium residual. - - -**Higher memory than Eyre-Milton:** ADMM requires 3 fields ($\varepsilon$, $\mathbf{e}$, $\lambda$) compared to 2 fields for the Eyre-Milton scheme. For large 3D microstructures with symmetric second-order tensor fields (6 components per voxel), the additional field can be significant. If memory is a constraint, the un-damped Eyre-Milton formulation is preferred. - - -**Slower convergence than un-damped Eyre-Milton:** The ADMM scheme corresponds to $\gamma = 1/2$ in the generalized framework, which has a larger contraction factor than the Eyre-Milton scheme ($\gamma = 0$). In practice, ADMM may require roughly twice as many iterations as Eyre-Milton for the same tolerance. The tradeoff is that ADMM provides direct access to the stress field $\lambda$ during iteration. - - -**Local nonlinear solve cost:** Like Eyre-Milton, each ADMM iteration requires solving a local nonlinear equation $(\frac{\partial w}{\partial \varepsilon} + \mathbf{C}^0)^{-1}$ at every grid point. For complex constitutive models, this local Newton iteration dominates the per-iteration cost and can be more expensive than a single forward stress evaluation in gradient-based schemes. - - -**Reference medium independence can mask suboptimal choices:** Since ADMM converges for any reference material $\mathbf{C}^0$, there is no divergence signal for a poor parameter choice. However, a poorly chosen $\alpha_0$ can drastically increase iteration count. The optimal choice for the fastest convergence still requires estimating the material contrast bounds $\alpha_-$ and $\alpha_+$. - - -## 5. References -- Schneider (2021) -- review of nonlinear FFT-based computational homogenization, ADMM and augmented Lagrangian formulations -- Michel et al. (2001) -- augmented Lagrangian method for FFT-based computational homogenization -- Monchiet and Bonnet (2012) -- generalized polarization framework unifying Douglas-Rachford and Peaceman-Rachford - diff --git a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-quasi-newton.md b/packages/akms/src/akms/_bundled/global_nodes/fft-solver-quasi-newton.md deleted file mode 100644 index 27d35a0..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/fft-solver-quasi-newton.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: fft-solver-quasi-newton -title: Quasi-Newton Methods (L-BFGS, Anderson Acceleration) -domain: fft-galerkin -subdomain: solver-algorithms -tags: -- solvers -- quasi-newton -- fft-galerkin -- convergence -- iterative -- nonlinear -- anderson-acceleration -status: established -confidence: 0.9 -source: hybrid -edges: -- to: fft-lippmann-schwinger - type: requires - weight: 0.8 - note: Anderson mixing accelerates the fixed-point L-S iteration -- to: fft-solver-basic-scheme - type: refines - weight: 1.0 - note: Anderson mixing wraps the basic scheme fixed-point iteration -- to: fft-solver-newton-krylov - type: refines - weight: 0.9 - note: Quasi-Newton methods are tangent-free alternatives to Newton-Krylov -- to: fft-solver-barzilai-borwein - type: refines - weight: 0.8 - note: Barzilai-Borwein can be interpreted as L-BFGS of depth 1 without line search -- to: fft-reference-medium - type: requires - weight: 0.6 - note: The underlying fixed-point scheme uses the reference medium -- to: fft-solver-krylov-cg - type: feeds-into - weight: 0.6 - note: Anderson mixing is equivalent to GMRES for linear problems -context_size: large -reading_priority: full -load_with: -- fft-solver-newton-krylov -- fft-solver-basic-scheme -- fft-solver-barzilai-borwein -content_ref: null -akms_schema: v2 ---- - -# Quasi-Newton Methods (L-BFGS, Anderson Acceleration) - -## Summary -Quasi-Newton methods for FFT-based homogenization approximate the tangent stiffness implicitly, avoiding the massive memory cost of storing the full tangent tensor. Two main approaches are used: L-BFGS (Limited-Memory BFGS) and Anderson acceleration (mixing). L-BFGS approximates the inverse Hessian via a two-loop recursion over the $m$ most recent gradient differences, requiring $2m + 4$ strain fields. However, L-BFGS is not competitive with the Barzilai-Borwein scheme for small-strain inelasticity because the FFT stiffness matrix is block-diagonal and sparse, making the L-BFGS overhead unwarranted. Anderson mixing of depth $m$ accelerates fixed-point iterations $\mathbf{u}_{k+1} = F(\mathbf{u}_k)$ by computing $\mathbf{u}_{k+1} = \sum \alpha_{i,m} F(\mathbf{u}_{k-i})$ with coefficients minimizing the mixed residual norm, requiring $2m + 2$ fields. Anderson mixing is equivalent to GMRES for linear problems and was introduced to FFT micromechanics as "nonlinear GMRES." With depth $m = 4$, Anderson-mixed basic scheme is the second-fastest method up to residual $10^{-3}$ and represents a highly robust, tangent-free general-purpose solver. - - -## 1. Core Concept -Quasi-Newton methods bypass the need for explicit tangent computation by building approximate curvature information from the iteration history. L-BFGS stores $m$ pairs of position and gradient differences and uses the two-loop recursion to efficiently compute an approximate Newton search direction without forming the full Hessian. Anderson mixing takes a different approach: given a fixed-point iteration $\mathbf{u}_{k+1} = F(\mathbf{u}_k)$ (such as the basic scheme), it stores the previous $m$ iterates and their images under $F$, then computes the next iterate as an optimal linear combination $\mathbf{u}_{k+1} = \sum_{i=0}^{m-1} \alpha_{i,m} F(\mathbf{u}_{k-i})$ where the coefficients minimize $\|\sum \alpha_{i,m}(\mathbf{u}_{k-i} - F(\mathbf{u}_{k-i}))\|^2$ subject to $\sum \alpha_{i,m} = 1$. This constrained least-squares problem is $m$-dimensional and involves only scalar products of residual vectors. Anderson mixing is a multi-secant method (Fang and Saad) and is equivalent to GMRES for linear problems (Walker and Ni). Both methods are tangent-free, making them applicable to black-box constitutive models. - - -## 2. Mathematical Formulation -The two quasi-Newton approaches differ in their mathematical foundation. L-BFGS operates in the optimization framework, approximating the inverse Hessian to compute search directions. Anderson mixing operates in the fixed-point iteration framework, optimally combining past iterates to accelerate convergence. Both achieve memory scaling linear in the depth parameter $m$ and avoid the $O(N_{\text{voxels}})$ tangent storage of Newton-Krylov. - - -**Anderson mixing update rule:** - -$$ -\mathbf{u}_{k+1} = \sum_{i=0}^{m-1} \alpha_{i,m} F(\mathbf{u}_{k-i}) -$$ - -where F is the fixed-point operator (e.g., basic scheme), m is the mixing depth - -**Anderson mixing coefficient optimization:** - -$$ -\left\|\sum_{i=0}^{m-1} \alpha_{i,m} (\mathbf{u}_{k-i} - F(\mathbf{u}_{k-i}))\right\|^2 \longrightarrow \min \quad \text{s.t.} \quad \sum_{i=0}^{m-1} \alpha_{i,m} = 1 -$$ - -where Linearly constrained quadratic optimization in m dimensions; involves only scalar products of residual vectors - -**L-BFGS memory requirement:** - -$$ -\text{Memory} = (2m + 4) \; \text{strain fields} -$$ - -where m is the depth (number of stored correction pairs) - -**Anderson mixing memory requirement:** - -$$ -\text{Memory} = (2m + 2) \; \text{strain fields} -$$ - -where m iterates u_{k-i} and m images F(u_{k-i}), plus 2 working fields - -**Barzilai-Borwein as L-BFGS depth 1:** - -$$ -\text{L-BFGS}(m=1, \text{no line search}) \equiv \text{Barzilai-Borwein} -$$ - -where The BB method can be interpreted as the simplest quasi-Newton approximation - -**Equivalence to GMRES for linear problems:** - -$$ -\text{Anderson mixing} \equiv \text{GMRES} \quad \text{(for linear } F \text{)} -$$ - -where Proven by Walker and Ni; Anderson mixing is a multi-secant method (Fang and Saad) - -**Notation:** - -- $F$ — Fixed-point operator (e.g., basic scheme iteration) -- $m$ — Mixing depth / number of stored history pairs -- $\alpha_{i,m}$ — Optimal mixing coefficients from constrained least-squares -- $\mathbf{u}_k$ — Displacement fluctuation field at iteration k - - -## 3. Algorithmic Implementation -**Algorithm: Anderson-Mixed Basic Scheme (Depth m)** - -$$ -\begin{algorithmic} -\State $Initialize \colon \mathbf{u}_0 = \mathbf{0}, \; F(\mathbf{u}_0) = \text{basic\_scheme\_step}(\mathbf{u}_0)$ -\While{$\|\mathbf{u}_k - F(\mathbf{u}_k)\| > \text{tol}$} - \State $Store \; \mathbf{u}_{k-i}, \; F(\mathbf{u}_{k-i}) \quad \text{for } i = 0, \ldots, \min(m-1, k)$ - \State $\text{Form residuals} \colon \mathbf{r}_{k-i} = \mathbf{u}_{k-i} - F(\mathbf{u}_{k-i})$ - \State $\text{Solve} \colon \alpha_{i,m} = \arg\min \|\sum \alpha_{i,m} \mathbf{r}_{k-i}\|^2 \; \text{s.t.} \; \sum \alpha_{i,m} = 1$ - \State $\mathbf{u}_{k+1} = \sum_{i=0}^{m-1} \alpha_{i,m} F(\mathbf{u}_{k-i})$ - \State $F(\mathbf{u}_{k+1}) = \text{basic\_scheme\_step}(\mathbf{u}_{k+1})$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -The basic scheme step (constitutive eval + FFT/iFFT) runs as GPU kernels. The m-dimensional QP is solved on the host (tiny problem). History buffer stores 2m+2 strain fields as Taichi fields. Scalar products for the QP are parallel reductions on GPU. Memory scales linearly with m; typical m=4 requires 10 strain fields. - -**Algorithm: L-BFGS Two-Loop Recursion for FFT Homogenization** - -$$ -\begin{algorithmic} -\State $Initialize \colon \mathbf{u}_0 = \mathbf{0}, \; \mathbf{g}_0 = \nabla W(\mathbf{u}_0)$ -\While{$\|\mathbf{g}_k\| > \text{tol}$} - \State $\text{Store} \colon \mathbf{s}_k = \mathbf{u}_k - \mathbf{u}_{k-1}, \quad \mathbf{y}_k = \mathbf{g}_k - \mathbf{g}_{k-1}$ - \State $\mathbf{q} \leftarrow \mathbf{g}_k$ - \State $\text{Backward loop} \colon \text{for } i = k, \ldots, k-m+1 \colon \rho_i = 1/\langle\mathbf{y}_i, \mathbf{s}_i\rangle, \; \alpha_i = \rho_i \langle\mathbf{s}_i, \mathbf{q}\rangle, \; \mathbf{q} \leftarrow \mathbf{q} - \alpha_i \mathbf{y}_i$ - \State $\mathbf{z} = H_k^0 \mathbf{q}, \quad H_k^0 = \langle\mathbf{s}_k, \mathbf{y}_k\rangle / \langle\mathbf{y}_k, \mathbf{y}_k\rangle \cdot \mathbf{Id}$ - \State $\text{Forward loop} \colon \text{for } i = k-m+1, \ldots, k \colon \beta_i = \rho_i \langle\mathbf{y}_i, \mathbf{z}\rangle, \; \mathbf{z} \leftarrow \mathbf{z} + (\alpha_i - \beta_i)\mathbf{s}_i$ - \State $\mathbf{d}_k = -\mathbf{z}$ - \State $\mathbf{u}_{k+1} = \mathbf{u}_k + s_k \mathbf{d}_k$ - \State $\mathbf{g}_{k+1} = \nabla W(\mathbf{u}_{k+1})$ -\EndWhile -\end{algorithmic} -$$ - -**Taichi Mapping:** -The two-loop recursion involves 2m inner products and 2m vector updates, all parallelizable on GPU. Gradient evaluation (constitutive law + FFT) is the dominant cost. Stores 2m+4 strain fields as Taichi fields. The backward/forward loops are lightweight compared to the FFT and constitutive evaluation. - - -## 4. Known Pitfalls -**L-BFGS not competitive for sparse FFT stiffness:** For FFT-based homogenization, the "stiffness matrix" (tangent operator) is block-diagonal and sparse. L-BFGS is designed for problems with dense Hessians and carries substantial computational overhead from the two-loop recursion over $m$ stored pairs. For small-strain inelasticity, L-BFGS is outperformed by the Barzilai-Borwein method, which is effectively L-BFGS of depth 1 without line search but avoids the overhead. - - -**Anderson mixing slows down for high accuracy:** The Anderson-mixed basic scheme with depth $m = 4$ is the second-fastest method up to a residual of $10^{-3}$, but slows down when pushing for higher accuracy (e.g., $10^{-5}$). This accuracy degradation likely results from the finite depth $m$ limiting the effective Krylov subspace dimension, causing the method to behave like a truncated GMRES. - - -**Memory scales linearly with depth m:** Anderson mixing requires $2m + 2$ strain fields and L-BFGS requires $2m + 4$ strain fields. For depth $m = 4$, Anderson needs 10 fields and L-BFGS needs 12 fields. At $512^3$ resolution (6 GB per strain field), this translates to 60-72 GB, comparable to Newton-CG. Practical GPU implementations must keep $m$ small (typically 3-5). - - -**No guaranteed convergence rate:** Unlike CG (with provable $\sqrt{\kappa}$ convergence) or Newton (with local quadratic convergence), quasi-Newton methods lack sharp convergence guarantees for the nonlinear FFT homogenization setting. Anderson mixing is a heuristic acceleration of the underlying fixed-point scheme, and its convergence can depend on the specific problem, microstructure, and material nonlinearity. - - -**Coefficient ill-conditioning at large depth:** The $m$-dimensional constrained least-squares problem for Anderson mixing coefficients can become ill-conditioned when the stored residual vectors become nearly linearly dependent. This occurs at large $m$ or when the iteration approaches convergence. Regularization (e.g., Tikhonov) or dropping old vectors may be needed. - - -## 5. References -- Schneider (2021) -- L-BFGS, Anderson mixing, comparison to Barzilai-Borwein, memory table -- Shanthraj et al. (2015) -- Anderson mixing as nonlinear GMRES for FFT homogenization -- Chen et al. (2019) -- Anderson-mixed basic scheme with depth m=4 for small strains -- Wicht et al. (2020) -- Comprehensive comparison of quasi-Newton methods for FFT homogenization -- Walker and Ni (2011) -- Equivalence of Anderson mixing and GMRES for linear problems -- Fang and Saad (2009) -- Anderson mixing as a multi-secant method - diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-extrusion.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-extrusion.md deleted file mode 100644 index 89242d7..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-extrusion.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: gmsh-extrusion -title: Gmsh Extrusion Operations -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- extrusion -- sweep -- layers -- prism -- recombine -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-geometry-api - type: requires - weight: 1.0 -- to: gmsh-structured-meshing - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Extrusion Operations - -## Summary - -Gmsh extrusion operations sweep 0D, 1D, and 2D geometrical entities and their meshes along translation, rotation, or combined twist paths to construct higher-dimensional entities. When extruding surface meshes, Gmsh generates 3D volumes structured in layers, producing tetrahedra by default or prisms/hexahedra/pyramids when the Recombine directive is specified. - -## 1. Core Concept - -Extrusion in Gmsh provides a structured sweeping mechanism to create curves from points, surfaces from curves, and volumes from surfaces. Extrude commands accept translation vectors, rotation axes, or helical twist parameters, alongside layer parameters (element counts and cumulative normalized heights). Mesh extrusion automatically generates conformal elements; triangulated base meshes yield tetrahedral elements that recombine into triangular prisms, whereas quadrangular base meshes recombine into hexahedra and pyramids. - -## 2. Mathematical Formulation - -**extrusion_translation** -$$ -\mathbf{x}_{ext} = \mathbf{x} + \mathbf{t} -$$ -_Source: Gmsh Reference Manual, Section 5.2.5, p. 104_ - -**extrusion_rotation** -$$ -\mathbf{x}_{ext} = \mathbf{x}_0 + \mathbf{R}(\mathbf{a}, \theta)(\mathbf{x} - \mathbf{x}_0) -$$ -_Source: Gmsh Reference Manual, Section 5.2.5, p. 104_ - -**extrusion_twist** -$$ -\mathbf{x}_{ext} = \mathbf{x}_0 + \mathbf{R}(\mathbf{a}, \theta)(\mathbf{x} - \mathbf{x}_0) + \mathbf{t} -$$ -_Source: Gmsh Reference Manual, Section 5.2.5, p. 104_ - -**extrusion_layer_height** -$$ -h_i \in (0, 1], \quad 0 < h_1 < h_2 < \dots < h_k = 1 -$$ -_Source: Gmsh Reference Manual, Section 5.3.2, p. 109_ - -**Notation:** -- {'\\mathbf{x}': 'Coordinates of a point prior to extrusion transformation'} -- {'\\mathbf{x}_{ext}': 'Transformed coordinates of a point after extrusion'} -- {'\\mathbf{t}': 'Translation vector (dx, dy, dz)'} -- {'\\mathbf{x}_0': 'Pivot point on the rotation axis'} -- {'\\mathbf{a}': 'Direction vector of the rotation axis'} -- {'\\theta': 'Angle of rotation in radians'} -- {'h_i': 'Normalized cumulative height fraction for layer i'} - - -## 3. Algorithmic Implementation - -**structured_mesh_extrusion** -$$ -\begin{algorithmic} -\State $\text{Input source surface } S, \text{ layer element counts } \{N_1, \dots, N_k\}, \text{ normalized layer heights } \{h_1, \dots, h_k\}, \text{ and recombination flag } R$ -\State $\text{Discretize source surface } S \text{ into 2D elements (triangles or quadrangles)}$ -\For{$i \text{ from } 1 \text{ to } k$} -\State $\text{Subdivide interval } [h_{i-1}, h_i] \text{ into } N_i \text{ element subdivisions along the extrusion vector}$ -\EndFor -\If{$R = \text{True}$} -\State $\text{Recombine tetrahedra generated from triangular base into prisms, or from quadrangular base into hexahedra and pyramids}$ -\Else -\EndIf -\Return $\text{Extruded 3D volume mesh } V \text{ with top boundary } S_{top} \text{ and lateral surface boundaries } S_{lat}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 5.3.2, p. 109-110_ - - -## 4. Known Pitfalls - -- **Rotation Angle Limit in Built-in CAD Kernel**: When using the built-in geometry kernel, rotation extrusion angles must be strictly less than \pi radians. For a full 360-degree extrusion sweep using the built-in kernel, at least 3 successive rotation extrusions are required. The OpenCASCADE kernel allows angles up to 2\pi. _(Source: Gmsh Reference Manual, Section 2.3, p. 22 & Section 5.2.5, p. 104)_ -- **Misconception of Triangular Prism Recombination**: Extruding a triangulated 2D surface mesh generates 3D tetrahedral elements by default. Specifying the Recombine option recombines these tetrahedra into triangular prisms (or into hexahedra/pyramids if the base surface mesh is quadrangular). Recombine does not convert triangular prisms into hexahedra. _(Source: Gmsh Reference Manual, Section 1.2, p. 9 & Section 5.3.2, p. 109)_ -- **Legacy Region Tag Specification in Layers Command**: Explicit specification of region tags within Layers commands is no longer supported. Generated volume and lateral surface entity tags must be captured programmatically using the array returned by the Extrude scripting command. _(Source: Gmsh Reference Manual, Section 5.3.2, p. 109-110)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-geometry-api.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-geometry-api.md deleted file mode 100644 index 1695b13..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-geometry-api.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -id: gmsh-geometry-api -title: Gmsh Geometry Definition (OCC & Built-in Kernels) -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- geometry -- OCC -- built-in -- boolean-ops -- CAD -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-physical-groups - type: feeds-into - weight: 0.5 -- to: gmsh-meshing-algorithms - type: feeds-into - weight: 0.5 -- to: gmsh-python-api - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Geometry Definition (OCC & Built-in Kernels) - -## Summary - -Gmsh defines geometric models using Boundary Representation (BRep) and constructive solid geometry (CSG) supported by two primary CAD engines: the built-in kernel and the OpenCASCADE (OCC) kernel. Elementary entities (points, curves, surfaces, volumes) are uniquely identified by a dimension-tag integer pair. Built-in geometries follow a strict bottom-up construction flow, whereas the OpenCASCADE kernel additionally supports top-down primitive creation (such as Rectangle, Sphere, and Box) and 3D boolean operations. - -## 1. Core Concept - -Geometry definition in Gmsh establishes the topological and geometric foundation for finite element meshing using Boundary Representation (BRep). Topological entities are categorized into four dimensions: 0D (points), 1D (curves), 2D (surfaces), and 3D (volumes), each identified by an entity tag pair (dim, tag) where tag is a positive integer. Gmsh interfaces two distinct CAD kernels: the native built-in kernel (`geo`) requiring explicit bottom-up topology assembly (points to curves to curve loops to surfaces), and the OpenCASCADE kernel (`occ`) enabling solid primitives, STEP/IGES import, and constructive solid geometry via boolean operations (union, intersection, difference, fragments). Kernel actions remain isolated until synchronized with the internal model. - -## 2. Mathematical Formulation - -**entity_identification** -$$ -e_i = (d_i, T_i), \quad d_i \in \{0, 1, 2, 3\}, \quad T_i \in \mathbb{Z}^+ -$$ -_Source: Gmsh Reference Manual, Section 1.1, p. 7-8_ - -**curve_parametrization** -$$ -\mathbf{x}(u) = (x(u), y(u), z(u)), \quad u \in [u_{min}, u_{max}] -$$ -_Source: Gmsh Reference Manual, Section 6.3, p. 133_ - -**surface_parametrization** -$$ -\mathbf{x}(u, v) = (x(u, v), y(u, v), z(u, v)), \quad (u, v) \in \Omega \subset \mathbb{R}^2 -$$ -_Source: Gmsh Reference Manual, Section 6.3, p. 133_ - -**occ_rectangle_primitive** -$$ -\mathbf{x}_{rect}(u, v) = \mathbf{x}_0 + u \cdot dx \, \mathbf{e}_x + v \cdot dy \, \mathbf{e}_y, \quad u, v \in [1] -$$ -_Source: Gmsh Reference Manual, Section 5.2.3, p. 102 & Section 6.8, p. 183_ - -**Notation:** -- {'d': 'Topological dimension (0 for point, 1 for curve, 2 for surface, 3 for volume)'} -- {'T': 'Strictly positive integer tag unique per dimension'} -- {'u, v, w': 'Parametric coordinates within the reference space of a model entity'} -- {'\\mathbf{x}': 'Coordinates (x, y, z) in 3D Euclidean space'} -- {'\\Omega': 'Parametric domain of a surface entity'} - - -## 3. Algorithmic Implementation - -**built_in_versus_occ_surface_creation** -$$ -\begin{algorithmic} -\State $\text{Define corner coordinates } (x_0, y_0, z_0), \text{ width } dx, \text{ height } dy, \text{ and characteristic length } l_c$ -\If{$\text{Kernel} = \text{Built-in}$} -\State $p_1 = \text{Point}(1) = \{x_0, y_0, z_0, l_c\}, \; p_2 = \text{Point}(2) = \{x_0+dx, y_0, z_0, l_c\}$ -\State $p_3 = \text{Point}(3) = \{x_0+dx, y_0+dy, z_0, l_c\}, \; p_4 = \text{Point}(4) = \{x_0, y_0+dy, z_0, l_c\}$ -\State $c_1 = \text{Line}(1) = \{p_1, p_2\}, \; c_2 = \text{Line}(2) = \{p_2, p_3\}, \; c_3 = \text{Line}(3) = \{p_3, p_4\}, \; c_4 = \text{Line}(4) = \{p_4, p_1\}$ -\State $L_1 = \text{Curve Loop}(1) = \{c_1, c_2, c_3, c_4\}$ -\State $S_1 = \text{Plane Surface}(1) = \{L_1\}$ -\ElsIf{$\text{Kernel} = \text{OpenCASCADE}$} -\State $\text{SetFactory}("OpenCASCADE")$ -\State $S_1 = \text{Rectangle}(1) = \{x_0, y_0, z_0, dx, dy\}$ -\EndIf -\State $\text{Synchronize CAD kernel data with internal Gmsh model structure}$ -\Return $\text{Surface entity } (2, S_1) \text{ ready for physical group assignment or meshing}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 2.1, p. 15-18 & Section 5.2.3, p. 102_ - - -## 4. Known Pitfalls - -- **Primitive Rectangle Unavailability in Built-in Kernel**: Attempting to create a rectangle primitive directly using the Rectangle command under the built-in geometry kernel causes a syntax error. Built-in surface creation requires a bottom-up construction sequence defining 4 corner points, 4 bounding lines, 1 curve loop, and 1 plane surface. Direct primitive commands such as Rectangle, Box, Sphere, and Cylinder are exclusive to the OpenCASCADE kernel. _(Source: Gmsh Reference Manual, Section 2.1, p. 18 & Section 5.2.3, p. 102)_ -- **Unsynchronized Kernel Model State**: Geometrical entities added or transformed via scripting or API calls in either the built-in (geo) or OpenCASCADE (occ) kernels are not visible to meshing algorithms or top-level model queries until a synchronization operation (e.g., SyncModel, gmsh.model.geo.synchronize(), or gmsh.model.occ.synchronize()) is executed. _(Source: Gmsh Reference Manual, Section 5.1.9, p. 99 & Section 6.6, p. 177)_ -- **Inability to Cross-Translate Geometry Formats**: Gmsh does not convert native geometry definitions between CAD kernels. Geometries created using the built-in kernel cannot be exported as OpenCASCADE BREP or STEP files, and OpenCASCADE models cannot be exported as Unrolled GEO files. _(Source: Gmsh Reference Manual, Section 2.2, p. 21 & Section C.4, p. 375)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-formats.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-formats.md deleted file mode 100644 index ea65c45..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-formats.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -id: gmsh-mesh-formats -title: Gmsh Mesh Export Formats -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- formats -- msh -- vtk -- abaqus-inp -- xdmf -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-physical-groups - type: requires - weight: 1.0 -- to: gmsh-python-api - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Mesh Export Formats - -## Summary - -Gmsh provides native export capabilities for finite element meshes across a broad spectrum of standard file formats, including MSH (versions 2.2, 4.0, and 4.1 in ASCII or binary), UNV, VTK, Abaqus INP, CGNS, MED, STL, BDF, PLY2, and SU2. Export formats can be selected automatically based on file extension, specified explicitly via the -format command-line switch or Mesh.Format option, or invoked programmatically using the API command gmsh.write(). - -## 1. Core Concept - -Mesh export in Gmsh translates generated 1D, 2D, and 3D conformal meshes into structured or unstructured solver-ready file formats. Export operations do not rely on external conversion tools or third-party libraries. By default, when physical groups are defined, Gmsh filters output files to export only elements assigned to at least one physical group. Setting Mesh.SaveAll=1 overrides this filter to save all elements regardless of physical group assignment. - -## 2. Mathematical Formulation - -**physical_group_element_filtering** -$$ -E_{saved} = \begin{cases} \{ e \in E \mid \exists P \in \mathcal{P}, e \in P \}, & \text{if } \text{Mesh.SaveAll} = 0 \\ E, & \text{if } \text{Mesh.SaveAll} = 1 \end{cases} -$$ -_Source: Gmsh Reference Manual, Section 1.2.3, p. 11-12 & Section 7.4, p. 267_ - -**msh_header_specification** -$$ -\text{MeshFormat} = (V, F, S), \quad V \in \{2.2, 4.0, 4.1\}, \quad F \in \{0, 1\}, \quad S = \text{sizeof(double)} -$$ -_Source: Gmsh Reference Manual, Section 10.1, p. 343-344_ - -**Notation:** -- {'E': 'Set of all generated finite element mesh entities'} -- {'\\mathcal{P}': 'Collection of user-defined physical groups'} -- {'E_{saved}': 'Set of mesh elements written to the output file'} -- {'V': 'MSH format version number (2.2, 4.0, or 4.1)'} -- {'F': 'File mode indicator (0 for ASCII, 1 for binary)'} -- {'S': 'Floating-point data size in bytes'} - - -## 3. Algorithmic Implementation - -**mesh_export_workflow** -$$ -\begin{algorithmic} -\State $\text{Input generated mesh } E, \text{ physical groups } \mathcal{P}, \text{ target filename } \text{fn}, \text{ and format directive } \text{fmt}$ -\If{$\text{fmt} = \text{"auto"}$} -\State $\text{Deduce target file format from the filename extension of } \text{fn} \text{ (e.g., } .msh, .unv, .vtk, .inp, .cgns, .med, .stl, .bdf\text{)}$ -\Else -\EndIf -\If{$\text{Mesh.SaveAll} = 0 \text{ and } |\mathcal{P}| > 0$} -\State $\text{Filter mesh to } E_{saved} = \{ e \in E \mid \exists P \in \mathcal{P}, e \in P \}$ -\Else -\EndIf -\State $\text{Write nodes, elements, and entity topology to } \text{fn} \text{ via API call } \text{gmsh.write(fn)} \text{ or script command } \text{Save } \text{fn}$ -\Return $\text{Exported mesh file } \text{fn}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 1.2.3, p. 11-12, Section 4, p. 83, & Section 6.1, p. 124_ - - -## 4. Known Pitfalls - -- **Element Omission Due to Physical Group Filtering**: When physical groups are defined in a Gmsh model, mesh export functions (such as Save or gmsh.write) default to exporting only elements assigned to at least one physical group. Elements not assigned to any physical group are omitted from output unless Mesh.SaveAll=1 or command-line option -save_all is set. _(Source: Gmsh Reference Manual, Section 1.2.3, p. 11-12 & Section 7.4, p. 267)_ -- **MSH Version Mismatch with Legacy Solvers**: Gmsh exports meshes in MSH 4.1 format by default. Legacy external solvers expecting MSH 2.2 syntax will fail to parse MSH 4 files unless Mesh.MshFileVersion = 2.2 is set in scripts/API or -format msh2 is specified on the command line. _(Source: Gmsh Reference Manual, Section 2.1, p. 17-18, Section 7.4, p. 261, & Section C.5, p. 377)_ -- **Unsupported File Extensions**: Gmsh exports directly to native supported formats (such as MSH, UNV, VTK, INP, CGNS, MED, STL, BDF, SU2). Attempting to export to unsupported formats like XDMF (.xmf/.h5) natively in Gmsh will cause export failures, as third-party conversion packages like meshio are not integrated into Gmsh. _(Source: Gmsh Reference Manual, Section 4, p. 83 & Section 7.4, p. 255)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-quality.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-quality.md deleted file mode 100644 index 5fce7e9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-quality.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -id: gmsh-mesh-quality -title: Gmsh Mesh Quality Metrics & Optimization -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- quality -- jacobian -- aspect-ratio -- skewness -- optimization -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-meshing-algorithms - type: refines - weight: 0.7 -- to: gmsh-mesh-size-control - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Mesh Quality Metrics & Optimization - -## Summary - -Gmsh provides native element quality evaluation metrics and mesh optimization algorithms for 2D and 3D finite element meshes. Quality metrics include the signed inverse condition number (SICN), signed inverse gradient error (SIGE), inscribed-to-circumscribed radius ratio (gamma), and minimal scaled Jacobian. Mesh quality can be improved using topological optimization, Laplace smoothing, node relocation, Netgen optimization, and high-order elastic untangling. - -## 1. Core Concept - -Mesh quality assessment and optimization in Gmsh ensure element validity and numerical stability for finite element solvers. Quality evaluation calculates geometric metrics such as SICN, SIGE, gamma, and Jacobian ratios across element types. Mesh optimization improves poor-quality elements using threshold-based local transformations (edge swaps, splits, collapses), node relocation, Laplace smoothing iterations, Netgen tetrahedral optimization, and high-order curvilinear mesh untangling. - -## 2. Mathematical Formulation - -**gamma_quality_metric** -$$ -\gamma = d \cdot \frac{r_{in}}{r_{circ}} -$$ -_Source: Gmsh Reference Manual, Section 7.4, p. 265 & Appendix C.5, p. 377_ - -**jacobian_determinant** -$$ -J = \det(\mathbf{J}(\mathbf{\xi})), \quad \mathbf{J} = \frac{\partial \mathbf{x}}{\partial \mathbf{\xi}} -$$ -_Source: Gmsh Reference Manual, Section 2.27, p. 74 & Section 6.4, p. 148_ - -**jacobian_ratio_metric** -$$ -Q_{disto} = \frac{\min_{\mathbf{\xi}} J(\mathbf{\xi})}{\max_{\mathbf{\xi}} J(\mathbf{\xi})} -$$ -_Source: Gmsh Reference Manual, Section 7.4, p. 265 & Section 9, p. 315_ - -**Notation:** -- {'r_{in}': 'Radius of the inscribed sphere or circle'} -- {'r_{circ}': 'Radius of the circumscribed sphere or circle'} -- {'\\gamma': 'Inscribed to circumscribed radius ratio quality metric'} -- {'\\mathbf{J}': 'Jacobian matrix mapping parametric reference coordinates to physical space'} -- {'J': 'Determinant of the Jacobian matrix'} -- {'Q_{disto}': 'Distortion quality metric based on Jacobian determinant ratio'} - - -## 3. Algorithmic Implementation - -**mesh_optimization_and_smoothing** -$$ -\begin{algorithmic} -\State $\text{Input mesh } M, \text{ optimization target threshold } Q_{thresh}, \text{ and maximum iterations } N_{iter}$ -\State $\text{Evaluate quality metric } Q(e) \text{ for each element } e \in M \text{ (e.g., SICN or } \gamma\text{)}$ -\State $\text{Identify low-quality element subset } M_{poor} = \{ e \in M \mid Q(e) < Q_{thresh} \}$ -\If{$|M_{poor}| > 0$} -\For{$k \text{ from } 1 \text{ to } N_{iter}$} -\State $\text{Perform local topological operations (edge swaps, splits, collapses) or Netgen optimization on } M_{poor}$ -\State $\text{Apply } N_{smooth} \text{ steps of Laplace smoothing or node relocation } (\text{Relocate2D / Relocate3D})$ -\State $\text{Re-evaluate } Q(e) \text{ for updated elements } e \in M_{poor}$ -\EndFor -\EndIf -\If{$\text{Mesh element order } p > 1 \text{ and high-order optimization enabled}$} -\State $\text{Optimize curvilinear nodes using elastic smoother or fast curving untangling algorithm } (\text{OptimizeMesh } \text{"HighOrder"})$ -\EndIf -\Return $\text{Optimized finite element mesh } M_{opt}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 1.2.1, p. 9, Section 5.3.3, p. 112, & Section 7.4, p. 263_ - - -## 4. Known Pitfalls - -- **Lloyd Smoothing Unavailability**: Gmsh does not implement Lloyd smoothing for mesh regularization. Mesh smoothing in Gmsh relies on Laplace smoothing (e.g., Mesh.Smoothing or OptimizeMesh "Laplace2D"), node relocation (Relocate2D/3D), or high-order elastic untangling. _(Source: Gmsh Reference Manual, Section 5.3.3, p. 112 & Section 7.4, p. 268)_ -- **Inverted High-Order Elements**: High-order element curved nodes can lead to negative Jacobian determinants (inverted elements) if boundary curvature is large. High-order optimization (OptimizeMesh "HighOrder" or "HighOrderElastic") must be run to untangle curved elements. _(Source: Gmsh Reference Manual, Section 1.5, p. 13 & Section 2.5, p. 30)_ -- **Misinterpreting Quality Metrics across Solvers**: Solver requirements for element quality vary by numerical scheme. Gmsh provides multiple quality metrics (SICN, SIGE, gamma, Disto), but Gmsh itself does not enforce a rigid universal solver threshold such as failing on quality < 0.1. _(Source: Gmsh Reference Manual, Section 7.4, p. 265 & Appendix C.5, p. 377)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-size-control.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-size-control.md deleted file mode 100644 index 8b87df9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-mesh-size-control.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -id: gmsh-mesh-size-control -title: Gmsh Mesh Size Control & Size Fields -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- mesh-size -- size-field -- attractor -- distance -- threshold -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-meshing-algorithms - type: requires - weight: 1.0 -- to: gmsh-geometry-api - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Mesh Size Control & Size Fields - -## Summary - -Gmsh controls mesh element sizes using point-based size specifications, curvature-adapted sizing, structured grid constraints, and general mesh size fields (such as Distance, Threshold, Box, MathEval, and PostView). To determine the local target element size at any spatial location, Gmsh computes the minimum of all active constraints, clamps the result within user-defined bounds [Mesh.MeshSizeMin, Mesh.MeshSizeMax], and scales it by Mesh.MeshSizeFactor. - -## 1. Core Concept - -Mesh size control in Gmsh prescribes local spatial resolution during bottom-up 1D, 2D, and 3D discretization. Target element sizes can be specified directly at CAD points, calculated automatically from local entity curvature, or defined dynamically using background size fields. Fields like Distance measure distance to geometric entities, Threshold maps distance to a range [SizeMin, SizeMax], Box imposes rectangular size step-changes, MathEval applies spatial mathematical functions, and Min combines multiple field outputs. When size fields drive discretization, disabling point-based and boundary-extended sizing prevents unwanted over-refinement. - -## 2. Mathematical Formulation - -**threshold_field_mapping** -$$ -h_{thresh}(d) = \begin{cases} h_{min}, & d \le d_{min} \\ h_{min} + \frac{d - d_{min}}{d_{max} - d_{min}}(h_{max} - h_{min}), & d_{min} < d < d_{max} \\ h_{max}, & d \ge d_{max} \end{cases} -$$ -_Source: Gmsh Reference Manual, Section 2.10, p. 38-39 & Section 8, p. 312_ - -**curvature_based_size** -$$ -h_{curv} = \frac{2\pi R}{N_{2\pi}} -$$ -_Source: Gmsh Reference Manual, Section 1.2.2, p. 10 & Section 7.4, p. 259_ - -**global_size_clamping** -$$ -h_{final} = \text{MeshSizeFactor} \cdot \max\left( h_{min\_bound}, \min\left( \min_i(h_i), h_{max\_bound} \right) \right) -$$ -_Source: Gmsh Reference Manual, Section 1.2.2, p. 11 & Section 2.10, p. 40_ - -**Notation:** -- {'d': 'Spatial distance to a specified point, curve, or surface entity'} -- {'d_{min}, d_{max}': 'Distance threshold bounds (DistMin, DistMax) for size field mapping'} -- {'h_{min}, h_{max}': 'Target element size bounds (SizeMin, SizeMax) within a Threshold field'} -- {'R': 'Local geometric radius of curvature'} -- {'N_{2\\pi}': 'Target element count per 2\\pi radians specified by Mesh.MeshSizeFromCurvature'} -- {'h_{final}': 'Final evaluated target element size at a given spatial coordinate'} - - -## 3. Algorithmic Implementation - -**mesh_size_evaluation_pipeline** -$$ -\begin{algorithmic} -\State $\text{Input coordinate } \mathbf{x}, \text{ geometry model entities, active fields } F_1, \dots, F_m, \text{ and global size options}$ -\If{$\text{Mesh.MeshSizeFromPoints} = 1$} -\State $\text{Interpolate size } h_{point}(\mathbf{x}) \text{ from prescribed point size values}$ -\EndIf -\If{$\text{Mesh.MeshSizeFromCurvature} > 0$} -\State $\text{Compute curvature size } h_{curv}(\mathbf{x}) = \frac{2\pi R(\mathbf{x})}{\text{Mesh.MeshSizeFromCurvature}}$ -\EndIf -\If{$\text{Background Field } F_{bg} \text{ is assigned}$} -\State $\text{Evaluate field size } h_{field}(\mathbf{x}) = F_{bg}(\mathbf{x})$ -\EndIf -\State $\text{Compute candidate minimum } h_{raw} = \min(h_{bbox}, h_{point}, h_{curv}, h_{field}, h_{bnd})$ -\State $\text{Clamp size: } h_{clamped} = \max(\text{Mesh.MeshSizeMin}, \min(h_{raw}, \text{Mesh.MeshSizeMax}))$ -\State $\text{Scale size: } h_{final} = h_{clamped} \cdot \text{Mesh.MeshSizeFactor}$ -\Return $\text{Local target mesh size } h_{final}(\mathbf{x})$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 1.2.2, p. 10-11 & Section 2.10, p. 39-40_ - - -## 4. Known Pitfalls - -- **Over-Refinement from Unset Global Size Options**: When mesh element size is intended to be governed entirely by a background size field, leaving Mesh.MeshSizeFromPoints=1, Mesh.MeshSizeFromCurvature>0, or Mesh.MeshSizeExtendFromBoundary=1 active can cause unintended over-refinement near geometry boundaries. These options should be explicitly set to 0 when using size fields. _(Source: Gmsh Reference Manual, Section 1.2.2, p. 11 & Section 2.10, p. 40)_ -- **Attractor Field Deprecation**: In Gmsh 4, the legacy Attractor field is a deprecated synonym for the Distance field. Size fields should be constructed using Distance fields combined with Threshold, MathEval, or Box fields. _(Source: Gmsh Reference Manual, Appendix D, p. 381 & Chapter 8, p. 297, 303)_ -- **Algorithm Sensitivity to Steep Size Gradients**: When using size fields with steep element size gradients, Frontal-Delaunay (Mesh.Algorithm = 6) can struggle or produce poor quality elements; switching to the standard 2D Delaunay algorithm (Mesh.Algorithm = 5) handles steep gradients more robustly. _(Source: Gmsh Reference Manual, Section 2.10, p. 40)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-meshing-algorithms.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-meshing-algorithms.md deleted file mode 100644 index 676f56f..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-meshing-algorithms.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: gmsh-meshing-algorithms -title: Gmsh Meshing Algorithms & Selection -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- meshing -- delaunay -- frontal -- HXT -- MeshAdapt -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-mesh-size-control - type: feeds-into - weight: 0.5 -- to: gmsh-structured-meshing - type: refines - weight: 0.7 -- to: gmsh-mesh-quality - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Meshing Algorithms & Selection - -## Summary - -Gmsh provides a range of 2D and 3D unstructured finite element meshing algorithms. In 2D, surface triangulation algorithms include Frontal-Delaunay (the default, Mesh.Algorithm=6), Delaunay, MeshAdapt, BAMG, and Frontal-Delaunay for Quads. In 3D, tetrahedral algorithms include 3D Delaunay (Mesh.Algorithm3D=1), Netgen Frontal (Mesh.Algorithm3D=4), MMG3D, and HXT (a fast, parallel reimplementation of the 3D Delaunay algorithm). - -## 1. Core Concept - -Algorithm selection in Gmsh governs the unstructured spatial discretization of 2D surfaces and 3D volumes. Unstructured meshing follows a strict bottom-up sequence: 1D boundary curves are meshed first, followed by 2D surface meshing, and finally 3D volume meshing. For 2D surface meshes, Frontal-Delaunay offers high element quality, standard Delaunay is optimal for large planar domains, and MeshAdapt provides robustness on complex curved geometries. For 3D volume meshes, standard 3D Delaunay supports pyramid creation, embedded entities, and size fields, while HXT provides fine-grained OpenMP parallel speedup. - -## 2. Mathematical Formulation - -**delaunay_circumcircle_criterion** -$$ -\|\mathbf{x} - \mathbf{c}_i\| < R_i -$$ -_Source: Gmsh Reference Manual, Section 1.2.1, p. 9_ - -**adimensional_circumradius_insertion** -$$ -\alpha_K = \frac{R_K}{h(\mathbf{c}_K)} -$$ -_Source: Gmsh Reference Manual, Section 1.2.1, p. 9_ - -**delaunay_time_complexity** -$$ -T(n) = \mathcal{O}(n \log n) -$$ -_Source: Gmsh Reference Manual, Section 1.2.1, p. 9_ - -**Notation:** -- {'\\mathbf{x}': 'Spatial coordinates of an inserted interior mesh node'} -- {'\\mathbf{c}_K': 'Circumcenter of finite element K'} -- {'R_K': 'Circumradius of finite element K'} -- {'h(\\mathbf{x})': 'Local target mesh element size evaluated at position \\mathbf{x}'} -- {'\\alpha_K': 'Adimensional circumradius ratio governing sequential point insertion'} - - -## 3. Algorithmic Implementation - -**unstructured_2d_and_3d_mesh_generation** -$$ -\begin{algorithmic} -\State $\text{Input model geometry, 1D boundary discretization, 2D algorithm option } A_{2D}, \text{ and 3D algorithm option } A_{3D}$ -\State $\text{Construct initial 2D Delaunay triangulation of 1D boundary nodes via divide-and-conquer}$ -\State $\text{Recover missing boundary curve edges using topological edge swaps}$ -\If{$A_{2D} = 6 \quad (\text{Frontal-Delaunay, Default})$} -\State $\text{Insert interior surface nodes along advancing fronts guided by local size } h(\mathbf{x})$ -\ElsIf{$A_{2D} = 5 \quad (\text{Delaunay})$} -\State $\text{Insert interior nodes sequentially at circumcenters of elements with maximum } \alpha_K$ -\ElsIf{$A_{2D} = 1 \quad (\text{MeshAdapt})$} -\State $\text{Apply local edge splits, collapses, and swaps to refine surface triangulation}$ -\EndIf -\If{$\text{Dimension} = 3$} -\If{$A_{3D} = 1 \quad (\text{Delaunay})$} -\State $\text{Build 3D bounding mesh, recover surface boundaries via TetGen/BR, and insert interior volume nodes}$ -\ElsIf{$A_{3D} = 10 \quad (\text{HXT})$} -\State $\text{Execute fine-grained parallel 3D Delaunay tetrahedralization across OpenMP threads}$ -\ElsIf{$A_{3D} = 4 \quad (\text{Frontal})$} -\State $\text{Generate 3D tetrahedral elements using Netgen advancing-front algorithm}$ -\EndIf -\EndIf -\Return $\text{Generated 2D surface or 3D volume finite element mesh}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 1.2.1, p. 9-10 & Section 7.4, p. 253_ - - -## 4. Known Pitfalls - -- **Misidentification of HXT Algorithm Target Element Type**: HXT is not a hexahedral generator using cube transformations; it is a fast, parallel multithreaded reimplementation of the 3D Delaunay algorithm designed specifically for tetrahedral mesh generation. _(Source: Gmsh Reference Manual, Section 1.2.1, p. 10 & Section 7.4, p. 253)_ -- **Misinterpreting Default 2D Meshing Algorithm**: MeshAdapt is not the default 2D meshing algorithm in Gmsh. The default 2D algorithm is Frontal-Delaunay (Mesh.Algorithm = 6). MeshAdapt (Mesh.Algorithm = 1) is automatically triggered as a fallback if Delaunay or Frontal-Delaunay fails. _(Source: Gmsh Reference Manual, Section 1.2.1, p. 10 & Section 7.4, p. 253)_ -- **Distinction Between 2D Frontal-Delaunay and 3D Frontal Algorithms**: Frontal is not a standalone 2D algorithm name in Gmsh. In 2D, the advancing-front algorithm is designated Frontal-Delaunay (Mesh.Algorithm = 6), whereas Frontal (Mesh.Algorithm3D = 4) specifically refers to Netgen's 3D advancing-front tetrahedral meshing algorithm. _(Source: Gmsh Reference Manual, Section 1.2.1, p. 9-10 & Section 7.4, p. 253)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-periodicity.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-periodicity.md deleted file mode 100644 index 98cc457..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-periodicity.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: gmsh-periodicity -title: Gmsh Mesh Periodicity -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- periodicity -- RVE -- homogenization -- affine-transform -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-geometry-api - type: requires - weight: 1.0 -- to: composite-homogenization - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Mesh Periodicity - -## Summary - -Gmsh supports periodic meshing constraints on 1D curves and 2D surfaces, enabling matching discretizations on opposing domain boundaries. Meshes on target (slave) entities are generated by copying and transforming the nodes and element topology from master entities using explicit translation, rotation, or 4x4 affine transformation matrices. The resulting node correspondences are maintained in model data and stored in MSH files within the \$Periodic section. - -## 1. Core Concept - -Mesh periodicity in Gmsh enforces identical nodal distributions and element connectivities between pairs of geometric boundaries (curves or surfaces). During mesh generation, the master entity is discretized first, and its nodal coordinates and element structures are mapped onto the slave entity via a prescribed geometric transformation (translation, rotation, or 4x4 affine matrix). In Gmsh GEO scripts, periodicity is established using commands such as Periodic Surface or Periodic Curve, while in the C++/Python API it is set using gmsh.model.mesh.setPeriodic(). - -## 2. Mathematical Formulation - -**affine_periodic_mapping** -$$ -\mathbf{x}_{slave} = \mathbf{A} \mathbf{x}_{master} + \mathbf{b} -$$ -_Source: Gmsh Reference Manual, Section 5.3.3, p. 113 & Section 6.4, p. 160_ - -**translation_periodic_mapping** -$$ -\mathbf{x}_{slave} = \mathbf{x}_{master} + \mathbf{t} -$$ -_Source: Gmsh Reference Manual, Section 2.18, p. 52 & Section 5.3.3, p. 113_ - -**rotation_periodic_mapping** -$$ -\mathbf{x}_{slave} = \mathbf{x}_0 + \mathbf{R}(\mathbf{a}, \theta)(\mathbf{x}_{master} - \mathbf{x}_0) -$$ -_Source: Gmsh Reference Manual, Section 2.18, p. 52 & Section 5.3.3, p. 113_ - -**Notation:** -- {'\\mathbf{x}_{master}': 'Nodal coordinates on the master geometric entity'} -- {'\\mathbf{x}_{slave}': 'Mapped nodal coordinates on the periodic slave geometric entity'} -- {'\\mathbf{t}': 'Translation vector (dx, dy, dz)'} -- {'\\mathbf{R}(\\mathbf{a}, \\theta)': '3D rotation matrix parameterized by axis a and angle \\theta'} -- {'\\mathbf{x}_0': 'Pivot point on the axis of rotation'} - - -## 3. Algorithmic Implementation - -**periodic_mesh_duplication** -$$ -\begin{algorithmic} -\State $\text{Input master entity } E_{master}, \text{ slave entity } E_{slave}, \text{ and transformation } \mathbf{T}_{affine}$ -\State $\text{Assign periodic constraint: } \text{Periodic } (E_{slave}) = (E_{master}) \, \mathbf{T}_{affine}$ -\State $\text{Generate unstructured or structured mesh on master entity } E_{master}$ -\For{$\text{each node } \mathbf{x}_i \in E_{master} \text{ and element } e_k \in E_{master}$} -\State $\text{Compute slave node coordinates: } \mathbf{x}_{i, slave} = \mathbf{T}_{affine}(\mathbf{x}_{i, master})$ -\State $\text{Create corresponding node and element topology on } E_{slave}$ -\EndFor -\State $\text{Store periodic node correspondence list in model registry and output } \$Periodic \text{ MSH section}$ -\Return $\text{Conformal periodic boundary mesh pair } (E_{master}, E_{slave})$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 2.18, p. 51-53 & Section 6.4, p. 160-161_ - - -## 4. Known Pitfalls - -- **Unstated Engineering Applications in Manual**: While periodic boundary meshing is widely used in FEA for representative volume element (RVE) homogenization, unit-cell models, and FFT solvers, the Gmsh manual defines periodicity strictly as a geometric/mesh copying mechanism without referencing specific continuum homogenization formulations. _(Source: Gmsh Reference Manual, Section 2.18, p. 51-53)_ -- **Parametrization and Orientation Inconsistency**: If master and slave surfaces have mismatched CAD parametrizations or orientations, direct copying without an explicit affine matrix or proper Mesh.HighOrderPeriodic configuration can lead to distorted or inverted surface elements. _(Source: Gmsh Reference Manual, Section 7.4, p. 256 & Appendix C.5, p. 377)_ -- **De-activation via Ignore Periodicity Option**: Enabling Mesh.IgnorePeriodicity = 1 or using the command-line flag -ignore_periocity disables periodic mesh copying, causing Gmsh to mesh master and slave entities independently as standard unstructured boundaries. _(Source: Gmsh Reference Manual, Section 4, p. 85 & Section 7.4, p. 257)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-physical-groups.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-physical-groups.md deleted file mode 100644 index 67a138f..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-physical-groups.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -id: gmsh-physical-groups -title: Gmsh Physical Groups & Entity Tagging -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- physical-groups -- BC -- material -- tagging -- export -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-geometry-api - type: requires - weight: 1.0 -- to: gmsh-mesh-formats - type: feeds-into - weight: 0.5 -context_size: small -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Physical Groups & Entity Tagging - -## Summary - -Gmsh physical groups collect elementary geometric entities into higher-level logical sets to represent boundaries, subdomains, materials, or functional regions. Physical groups are identified by topological dimension (0D to 3D) and a positive integer tag or string label. When physical groups are defined, mesh export functions default to saving only the elements belonging to at least one physical group, unless Mesh.SaveAll is enabled. - -## 1. Core Concept - -Physical groups bridge geometry definition and solver pre-processing in Gmsh by associating groups of 0D points, 1D curves, 2D surfaces, or 3D volumes with domain boundary conditions, functional subregions, or material classifications. Each physical group is assigned a dimension and a unique tag (or string name) per dimension. During mesh export to formats like MSH, UNV, or INP, physical group tags dictate element filtering and group tagging, ensuring only relevant subdomain or boundary elements are output unless Mesh.SaveAll=1 is set. - -## 2. Mathematical Formulation - -**physical_group_definition** -$$ -P_d^{(k)} = \{ e_{d,i} \mid \text{dim}(e_{d,i}) = d, \, i \in I_k \} -$$ -_Source: Gmsh Reference Manual, Section 1.1, p. 7-8 & Section 1.2.3, p. 11_ - -**mesh_element_export_filtering** -$$ -E_{export} = \begin{cases} \bigcup_{d,k} \{ m \in M \mid \exists P_d^{(k)} \in \mathcal{P}, \text{entity}(m) \in P_d^{(k)} \}, & \text{if } \text{Mesh.SaveAll} = 0 \\ M, & \text{if } \text{Mesh.SaveAll} = 1 \end{cases} -$$ -_Source: Gmsh Reference Manual, Section 1.2.3, p. 11-12 & Section 2.1, p. 17_ - -**Notation:** -- {'P_d^{(k)}': 'Physical group of dimension d with identification tag k'} -- {'e_{d,i}': 'Elementary geometric entity i of dimension d'} -- {'\\mathcal{P}': 'Collection of all user-defined physical groups in the model'} -- {'M': 'Set of all finite element mesh entities generated by Gmsh'} -- {'E_{export}': 'Subset of mesh elements written to output mesh files'} - - -## 3. Algorithmic Implementation - -**physical_group_creation_and_export_filtering** -$$ -\begin{algorithmic} -\State $\text{Input elementary entities } \{e_{d,1}, \dots, e_{d,m}\}, \text{ target dimension } d, \text{ group tag } k, \text{ and string name } N$ -\If{$\text{Scripting / API environment}$} -\State $\text{Execute } \text{Physical Curve}(k) = \{e_{1,1}, \dots\} \text{ or } \text{gmsh.model.addPhysicalGroup}(d, \text{tags}, k, N)$ -\EndIf -\State $\text{Register group } P_d^{(k)} \text{ in model database associated with name } N$ -\State $\text{Generate mesh elements } M \text{ across all model entities}$ -\If{$\text{Mesh.SaveAll} = 0 \text{ and } |\mathcal{P}| > 0$} -\State $\text{Filter elements: retain } m \in M \text{ if } \text{entity}(m) \in P_d^{(k)} \text{ for some } P_d^{(k)} \in \mathcal{P}$ -\Else -\EndIf -\Return $\text{Filtered element set } E_{export} \text{ written to output mesh file}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 1.2.3, p. 11-12, Section 2.1, p. 17, & Section 6.3, p. 128_ - - -## 4. Known Pitfalls - -- **Unintended Element Omission on Export**: When any physical group is defined in a model, Gmsh defaults to exporting only elements associated with defined physical groups. Unassigned elements are silently omitted from output files unless Mesh.SaveAll = 1 or -save_all is set. _(Source: Gmsh Reference Manual, Section 1.2.3, p. 11-12 & Section 2.1, p. 17)_ -- **Inaccurate Standardization of Naming and Contact Pair Claims**: Physical groups are used broadly for boundary conditions ("boundary with Neumann condition"), materials ("steel"), or geometry parts ("left wing"). Gmsh does not mandate a rigid "1 per BC" pattern, hierarchical names like "fixed_left", or contact pair assignments. _(Source: Gmsh Reference Manual, Section 1.2.3, p. 11 & Section 2.1, p. 17)_ -- **Physical Group Discard in Legacy Formats**: In certain legacy mesh formats (such as MSH2), enabling Mesh.SaveAll = 1 causes Gmsh to discard physical group definitions altogether during export. _(Source: Gmsh Reference Manual, Section 1.2.3, p. 12)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-python-api.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-python-api.md deleted file mode 100644 index e2d3064..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-python-api.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -id: gmsh-python-api -title: Gmsh Python API Patterns -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- python -- scripting -- parametric -- batch -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-geometry-api - type: refines - weight: 0.7 -- to: gmsh-mesh-formats - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Python API Patterns - -## Summary - -The Gmsh Python Application Programming Interface (API) provides a purely functional object-oriented and C-compatible interface (`gmsh.py`) to Gmsh's internal data structures, geometry kernels, meshing algorithms, post-processing modules, and option server. Python API programs follow a structured lifecycle: initializing the session with `gmsh.initialize()`, constructing geometries in kernel namespaces (`gmsh.model.geo` or `gmsh.model.occ`), synchronizing kernel data once, setting physical groups and meshing constraints, generating meshes, exporting output files, and terminating via `gmsh.finalize()`. - -## 1. Core Concept - -The Gmsh Python API reflects Gmsh's internal data model by organizing functional operations under specific top-level namespaces (`gmsh.model`, `gmsh.model.mesh`, `gmsh.model.geo`, `gmsh.model.occ`, `gmsh.option`, `gmsh.view`, `gmsh.plugin`, and `gmsh.onelab`). Model entities are referenced as `(dim, tag)` integer pairs. Rather than translating CAD data into an intermediate format, Gmsh queries native CAD kernel data directly. To minimize performance overhead, script developers should batch geometric definitions and minimize synchronization calls (`gmsh.model.occ.synchronize()`), as synchronization transfers native CAD data to the primary Gmsh model registry. - -## 2. Mathematical Formulation - -**contiguous_coordinate_array** -$$ -\mathbf{X} = (x_1, y_1, z_1, x_2, y_2, z_2, \dots, x_N, y_N, z_N)^T \in \mathbb{R}^{3N} -$$ -_Source: Gmsh Reference Manual, Section 6.4, p. 140-142_ - -**mesh_size_callback_signature** -$$ -h_{target} = f(d, T, x, y, z, h_{default}) -$$ -_Source: Gmsh Reference Manual, Section 6.4, p. 155-156_ - -**Notation:** -- {'d': 'Topological entity dimension (0 for point, 1 for curve, 2 for surface, 3 for volume)'} -- {'T': 'Strictly positive integer entity tag'} -- {'\\mathbf{X}': 'Flattened 1D array of 3D nodal coordinates (x, y, z)'} -- {'h_{default}': 'Default target element size computed by Gmsh prior to callback invocation'} -- {'h_{target}': 'Custom target element size evaluated and returned by a Python size callback'} - - -## 3. Algorithmic Implementation - -**python_api_cad_and_mesh_workflow** -$$ -\begin{algorithmic} -\State $\text{Initialize API via } \text{gmsh.initialize()}, \text{ and create model } \text{gmsh.model.add}(\text{"model\_name"})$ -\State $\text{Define geometry using CAD kernel functions in } \text{gmsh.model.occ} \text{ or } \text{gmsh.model.geo}$ -\State $\text{Synchronize CAD kernel data once with main model via } \text{gmsh.model.occ.synchronize()}$ -\State $\text{Assign physical groups using } \text{gmsh.model.addPhysicalGroup}(d, \text{tags}, k, N)$ -\State $\text{Configure meshing options and size callbacks via } \text{gmsh.option.setNumber} \text{ and } \text{gmsh.model.mesh.setSizeCallback}$ -\State $\text{Generate mesh of target dimension } d \text{ using } \text{gmsh.model.mesh.generate}(d)$ -\State $\text{Export finite element mesh to file via } \text{gmsh.write}(\text{"output.msh"})$ -\State $\text{Finalize API session and release internal memory using } \text{gmsh.finalize()}$ -\Return $\text{Exported finite element mesh file}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 6, p. 121-124, Section 6.3, p. 126-128, & Section 6.6, p. 177_ - - -## 4. Known Pitfalls - -- **Excessive CAD Synchronization Points**: Executing synchronize() after every individual CAD definition or transformation incurs substantial computational overhead. The manual explicitly advises minimizing synchronization calls by batching CAD entity creation and executing synchronize() once before model queries, physical group assignments, or meshing. _(Source: Gmsh Reference Manual, Section 6.6, p. 177 & Section 6.8, p. 198)_ -- **Uninitialized or Unfinalized API Session State**: Invoking Gmsh API functions without first executing gmsh.initialize() causes runtime exceptions. Omitting gmsh.finalize() at script completion prevents proper cleanup of allocated memory, file handles, and internal server states. _(Source: Gmsh Reference Manual, Section 6.1, p. 122-123)_ -- **Querying Unsynchronized CAD Entities Outside Kernel Namespace**: Attempting to query or manipulate newly created CAD entities using top-level functions in gmsh.model or gmsh.model.mesh prior to calling synchronize() results in missing entity errors, as CAD kernel representations remain isolated within their respective kernel namespaces until explicitly synchronized. _(Source: Gmsh Reference Manual, Section 6, p. 121-122 & Section 6.6, p. 177)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/gmsh-structured-meshing.md b/packages/akms/src/akms/_bundled/global_nodes/gmsh-structured-meshing.md deleted file mode 100644 index a023b19..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/gmsh-structured-meshing.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: gmsh-structured-meshing -title: Gmsh Structured & Transfinite Meshing -domain: computational-mechanics -subdomain: mesh-generation -tags: -- gmsh -- transfinite -- structured -- recombination -- progression -status: established -confidence: 0.9 -source: hybrid -edges: -- to: gmsh-meshing-algorithms - type: refines - weight: 0.7 -- to: gmsh-mesh-size-control - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Gmsh Structured & Transfinite Meshing - -## Summary - -Gmsh supports structured and semi-structured mesh generation through transfinite mesh constraints and extruded surface/volume operations. Transfinite meshing maps structured topological grids onto 1D curves, 2D surfaces, and 3D volumes by interpolating boundary node distributions. Transfinite surfaces support 3 or 4 boundary corners, while transfinite volumes support 5- or 6-face regions with 6 or 8 corners. Triangular or tetrahedral meshes generated by transfinite interpolation can be recombined into quadrangles, prisms, or hexahedra using recombination directives and smoothed via elliptic grid smoothers. - -## 1. Core Concept - -Transfinite meshing in Gmsh enforces a structured grid topology on geometric entities by mapping prescribed nodal distributions from boundary curves into surface interiors or volume domains via transfinite interpolation. 1D boundary curves are constrained using `Transfinite Curve` with uniform spacing, geometric progressions, or bump distributions. 2D surfaces bounded by 3 or 4 corner points (or volumes bounded by 5 or 6 faces with 6 or 8 corners) are mapped using `Transfinite Surface` and `Transfinite Volume`. Recombination commands (`Recombine`) merge simplicial elements into structured quads or hexahedra, while `Mesh.Smoothing` applies elliptic smoothing to optimize grid line orthogonality. - -## 2. Mathematical Formulation - -**transfinite_curve_progression** -$$ -L_i = L_1 \cdot r^{i-1}, \quad x_i = x_0 + L_1 \frac{1 - r^i}{1 - r} -$$ -_Source: Gmsh Reference Manual, Section 5.3.2, p. 111_ - -**transfinite_surface_interpolation** -$$ -\mathbf{x}(u, v) = (1-u)(1-v)\mathbf{x}_{0,0} + u(1-v)\mathbf{x}_{1,0} + (1-u)v\mathbf{x}_{0,1} + uv\mathbf{x}_{1,1} -$$ -_Source: Gmsh Reference Manual, Section 2.6, p. 31 & Section 5.3.2, p. 111_ - -**recombination_angle_threshold** -$$ -|\theta_{quad} - \frac{\pi}{2}| \le \theta_{max} -$$ -_Source: Gmsh Reference Manual, Section 5.3.3, p. 114 & Section 7.4, p. 266_ - -**Notation:** -- {'L_i': 'Length of the i-th element segment along a transfinite curve'} -- {'r': 'Geometric progression ratio for node distribution along a curve'} -- {'u, v': 'Normalized parametric coordinates in reference domain [1]'} -- {'\\mathbf{x}_{ij}': 'Spatial coordinates of surface corner point (i, j)'} -- {'\\theta_{quad}': 'Interior angle of a recombined quadrilateral element'} -- {'\\theta_{max}': 'Maximum allowed deviation angle from a right angle during recombination'} - - -## 3. Algorithmic Implementation - -**transfinite_mesh_generation** -$$ -\begin{algorithmic} -\State $\text{Input surface } S \text{ or volume } V, \text{ boundary curves } \{C_j\}, \text{ node counts } N_j, \text{ progression ratios } r_j, \text{ and corner tags } \{P_k\}$ -\For{$\text{each boundary curve } C_j$} -\State $\text{Discretize } C_j \text{ into } N_j \text{ nodes using uniform spacing, geometric progression } r_j, \text{ or bump distribution}$ -\EndFor -\If{$\text{Target entity is surface } S$} -\State $\text{Verify boundary has } 3 \text{ or } 4 \text{ corner points } \{P_k\}; \text{ apply 2D transfinite blending interpolation in parametric space}$ -\If{$\text{Recombine Surface directive is enabled}$} -\State $\text{Combine pairs of triangles into quadrangles using Blossom or simple minimum-cost matching}$ -\Else -\EndIf -\ElsIf{$\text{Target entity is volume } V$} -\State $\text{Verify volume has } 5 \text{ or } 6 \text{ bounding faces and } 6 \text{ or } 8 \text{ corner points; apply 3D transfinite interpolation}$ -\EndIf -\If{$\text{Mesh.Smoothing } > 0$} -\State $\text{Apply } N_{smooth} \text{ iterations of elliptic grid smoothing to the structured mesh}$ -\EndIf -\Return $\text{Structured 2D or 3D transfinite finite element mesh}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Gmsh Reference Manual, Section 2.6, p. 31-32, Section 5.3.2, p. 111-112, & Section 5.3.3, p. 115_ - - -## 4. Known Pitfalls - -- **Mismatched Corner Counts in Transfinite Constraints**: Transfinite Surface constraints require 3 or 4 corners on the boundary (or explicit specification of 3 or 4 corner point tags if the boundary curve loop contains more points). Transfinite Volume requires 5- or 6-face volumes bounded by 6 or 8 corner points. Attempting transfinite meshing on arbitrary multi-sided topologies without proper corner definitions causes generation errors. _(Source: Gmsh Reference Manual, Section 2.6, p. 31-32 & Section 5.3.2, p. 111-112)_ -- **Unstated Engineering Use Cases in Manual**: While transfinite meshing is commonly used in computational mechanics for structured grid generation, benchmark problems, or FFT solvers, the Gmsh reference manual defines transfinite meshing strictly by its geometric mapping algorithms without referencing specific engineering analysis workflows. _(Source: Gmsh Reference Manual, Section 2.6, p. 30-32 & Section 5.3.2, p. 109-112)_ -- **Opposing Edge Node Count Discrepancy**: In transfinite surface meshing, opposing boundary curves must be assigned matching node counts. If opposing curves have inconsistent node numbers, transfinite grid mapping cannot construct a conformal structured mesh. _(Source: Gmsh Reference Manual, Section 2.6, p. 31 & Section 5.3.2, p. 111)_ - -## References - -- Gmsh Reference Manual, Version 4.11.0 (development version), Christophe Geuzaine and Jean-François Remacle, 2022. diff --git a/packages/akms/src/akms/_bundled/global_nodes/homogenization-cell-problem.md b/packages/akms/src/akms/_bundled/global_nodes/homogenization-cell-problem.md deleted file mode 100644 index bc51558..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/homogenization-cell-problem.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: homogenization-cell-problem -title: Periodic Cell Problem & RVE Theory -domain: fft-galerkin -subdomain: spectral-operators -tags: -- homogenization -- periodic-bc -- micromechanics -- continuum-mechanics -- fft-galerkin -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: fft-lippmann-schwinger - type: feeds-into - weight: 1.0 - note: Cell problem is reformulated as Lippmann-Schwinger integral equation -- to: fft-periodic-bc - type: requires - weight: 0.9 - note: Cell problem assumes periodic boundary conditions -- to: fft-galerkin-basics - type: feeds-into - weight: 0.8 - note: Galerkin discretization solves the cell problem in Fourier space -context_size: medium -reading_priority: full -load_with: -- fft-lippmann-schwinger -- fft-periodic-bc -content_ref: null -akms_schema: v2 ---- - -# Periodic Cell Problem & RVE Theory - -## Summary -The periodic cell problem is the foundational boundary value problem in FFT-based computational homogenization. It seeks the microscopic strain and stress fields within a representative volume element (RVE) that satisfy equilibrium, compatibility, periodic boundary conditions, and a volume-averaging constraint linking micro to macro scales. The periodicity of the domain enables reformulation as a Lippmann-Schwinger integral equation solvable via FFT, yielding O(N log N) computational cost and direct compatibility with voxelized microstructure images. RVE representativeness requires quantifying both dispersion (variance at fixed size) and bias (mean shift with increasing size). - - -## 1. Core Concept -Homogenization theory provides the mathematical basis for deriving effective macroscopic constitutive laws from explicitly described microstructural details and local constitutive behaviors. The cell problem is the PDE with discontinuous coefficients that must be solved on a sufficiently large representative volume element (RVE). The domain $\Omega$ is typically a rectangular parallelepiped divided into sub-regions representing different material phases. Periodic boundary conditions are applied because they empirically produce results with smaller bias than Dirichlet or Neumann conditions. The periodicity of the fields is what makes FFT-based methods viable: spatial convolutions become simple products in Fourier space, enabling efficient $\mathcal{O}(N \log N)$ solution without mesh generation. - - -## 2. Mathematical Formulation -The governing equations of the periodic cell problem in a small-strain elastic setting seek the local strain and stress fields within a heterogeneous domain $\Omega$ that simultaneously satisfy equilibrium, compatibility, periodic boundary conditions, and a macroscopic loading constraint. The system is closed by the local constitutive law relating stress to strain via the spatially varying stiffness tensor. - - -**Equilibrium (linear momentum balance):** - -$$ -\nabla \cdot \boldsymbol{\sigma}(\mathbf{x}) = 0 -$$ - -where sigma(x) is the local Cauchy stress tensor, nabla-dot is the divergence operator - -**Volume averaging constraint:** - -$$ -\langle \boldsymbol{\varepsilon}(\mathbf{x}) \rangle_\Omega = \bar{\boldsymbol{\varepsilon}} -$$ - -where angle brackets denote spatial average over Omega, epsilon-bar is the prescribed macroscopic strain - -**Strain compatibility:** - -$$ -\boldsymbol{\varepsilon}(\mathbf{x}) = \nabla^s \mathbf{u}(\mathbf{x}) -$$ - -where nabla-s is the symmetric gradient operator, u(x) is the local displacement field - -**Constitutive law (linear elasticity):** - -$$ -\boldsymbol{\sigma}(\mathbf{x}) = \mathbf{C}(\mathbf{x}) : \boldsymbol{\varepsilon}(\mathbf{x}) -$$ - -where C(x) is the local fourth-order stiffness tensor with major and minor symmetries - -**Boundary conditions:** - -$$ -\boldsymbol{\varepsilon}(\mathbf{x}) \text{ periodic}, \quad \boldsymbol{\sigma}(\mathbf{x}) \cdot \mathbf{n}(\mathbf{x}) \text{ anti-periodic} -$$ - -where n(x) is the outward unit normal on the boundary of the periodic domain Omega - -**Strain decomposition:** - -$$ -\boldsymbol{\varepsilon}(\mathbf{x}) = \bar{\boldsymbol{\varepsilon}} + \tilde{\boldsymbol{\varepsilon}}(\mathbf{x}), \quad \langle \tilde{\boldsymbol{\varepsilon}}(\mathbf{x}) \rangle_\Omega = 0 -$$ - -where epsilon-tilde(x) is the periodic strain fluctuation field with zero mean - -**Notation:** - -- $\boldsymbol{\sigma}$ — Cauchy stress tensor -- $\boldsymbol{\varepsilon}$ — Infinitesimal strain tensor -- $\bar{\boldsymbol{\varepsilon}}$ — Prescribed macroscopic strain -- $\tilde{\boldsymbol{\varepsilon}}$ — Periodic strain fluctuation (zero mean) -- $\mathbf{C}$ — Fourth-order stiffness tensor -- $\mathbf{u}$ — Displacement field -- $\Omega$ — Periodic computational domain (RVE) -- $\nabla^s$ — Symmetric gradient operator -- $\mathbf{n}$ — Outward unit normal on domain boundary - - -## 3. Algorithmic Implementation -Not applicable — this is a foundational concept node defining the boundary value problem, not an algorithmic procedure. - -## 4. Known Pitfalls -**RVE size insufficiency:** If the RVE is too small, statistical randomness of the microstructure dominates and predicted macroscopic properties become unreliable. Representativeness must be verified by quantifying both dispersion (standard deviation at fixed cell size) and bias (change in empirical mean with increasing cell size). There is no universal formula for minimum RVE size — it depends on the contrast ratio, volume fraction, and property of interest. - - -**Periodicity assumption failure:** Standard FFT approaches strictly require periodic boundary conditions. This assumption fails when modeling non-periodic features such as finite-sized components, localized fracture, or wave scattering. Workarounds include Fourier Continuation (FC) methods or Bloch boundary conditions, but these add significant complexity. - - -**Gibbs phenomenon at material interfaces:** The basic Moulinec-Suquet discretization exhibits high-frequency oscillations (ringing artifacts) near sharp material interfaces due to truncation of Fourier series. This is particularly severe for high-contrast materials and can produce unphysical stress concentrations at interfaces. - - -**Infinite contrast degeneracy:** For porous materials (voids) or rigid inclusions, the basic continuous FFT scheme can fail completely. Trigonometric polynomials attempt a continuous elastic extension into pore space, and because they are global, small numerical errors at solid-pore boundaries propagate throughout the entire RVE. In highly porous foams, the average stress in the basic scheme iterates may falsely converge to zero. - - -**Uniform grid constraint:** FFT-based solvers require a uniform regular grid, meaning microstructural interfaces must be voxelized rather than smoothly meshed. This prevents local mesh refinement near features of interest and can require very fine grids to adequately resolve thin layers or small inclusions. - - -## 5. References -- Schneider (2021) — Review of nonlinear FFT-based computational homogenization, §1 -- Lucarini et al. (2022) — FFT-based approaches review, §2, §3.1 - diff --git a/packages/akms/src/akms/_bundled/global_nodes/kinematics-convected-coordinates.md b/packages/akms/src/akms/_bundled/global_nodes/kinematics-convected-coordinates.md deleted file mode 100644 index d7dfe39..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/kinematics-convected-coordinates.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: kinematics-convected-coordinates -title: Convected Coordinate System -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- convected-coordinates -- curvilinear -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-curvilinear-bases - type: requires - weight: 1.0 -- to: tensor-metric - type: requires - weight: 1.0 -- to: kinematics-motion-deformation-gradient - type: refines - weight: 0.9 -- to: kinematics-strain-tensors - type: feeds-into - weight: 1.0 -- to: fem-tl-b-matrix - type: feeds-into - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Convected Coordinate System - -## Summary - -Convected coordinates track continuum deformation by embedding a curvilinear coordinate system into the material body that deforms continuously with the motion. Tensor components defined relative to convected base vectors implicitly absorb geometric deformation, simplifying strain definitions via metric tensor changes and enabling objective convected stress rate formulations. - -## 1. Core Concept - -In a convected coordinate description, curvilinear coordinates \(\theta^i\) are attached to material points in the reference configuration and remain continuously bound to those same material points throughout the motion. As the body deforms, the covariant base vectors \(\mathbf{g}_i = \partial \mathbf{x} / \partial \theta^i\) stretch and rotate with the continuum. Deformations are measured directly through changes in the metric tensor components \(g_{ij} = \mathbf{g}_i \cdot \mathbf{g}_j\) relative to reference metric components \(G_{ij} = \mathbf{G}_i \cdot \mathbf{G}_j\). Convected stress rates differentiate tensor components directly with respect to time in the convected frame, automatically yielding frame-invariant objective rate measures. - -## 2. Mathematical Formulation - -**Convected Base Vectors and Metric Tensor Evolution** -$$ -\mathbf{g}_i = \frac{\partial \mathbf{x}}{\partial \theta^i} = F \mathbf{G}_i, \quad g_{ij} = \mathbf{g}_i \cdot \mathbf{g}_j = F^k{}_i F^k{}_j G_{ij} -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.3, p. 34; Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.62, p. 1_ - -**Convected Green-Lagrange Strain Tensor Components** -$$ -E_{ij} = \frac{1}{2} (g_{ij} - G_{ij}) -$$ -_Source: Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf, Sec. 2.12, p. 2; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.3, p. 34_ - -**Convected Rate of Kirchhoff Stress** -$$ -\tau^{\nabla c} = \dot{\tau}_{ij} \mathbf{g}^i \otimes \mathbf{g}^j = C^c_{ijkl} D_{kl} \mathbf{g}^i \otimes \mathbf{g}^j -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, p. 779 & App. 3.5, p. 137; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Sec. 4.3, p. 23_ - -**Pull-Back Transformation of Covariant Strain** -$$ -E = \phi^* e = \frac{1}{2} (\phi^* g - G) -$$ -_Source: Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf, Sec. 2.12, Eqs. 2.12.46–2.12.51, pp. 1–2; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.3, p. 34_ - -**Notation:** -{'\\theta^i': 'Convected curvilinear coordinates bound to material points.', '\\mathbf{G}_i': 'Reference covariant basis vector.', '\\mathbf{g}_i': 'Deformed covariant basis vector in current configuration.', 'G_{ij}': 'Reference metric tensor components.', 'g_{ij}': 'Current metric tensor components.', 'E_{ij}': 'Green-Lagrange strain components in convected system.', '\\tau^{\\nabla c}': 'Convected objective rate of Kirchhoff stress tensor.', 'C^c_{ijkl}': 'Material tangent constitutive tensor relating convected stress rate to rate of deformation.'} - - -## 3. Algorithmic Implementation - -**Convected Metric and Strain Tensor Computation Algorithm** -$$ -\begin{algorithmic} -\State $Given reference nodal position X, current position x(X,t), and element parametric coordinates \theta^i$ -\State $Compute reference covariant base vectors \mathbf{G}_i \gets \frac{\partial X}{\partial \theta^i} \text{ and metric } G_{ij} \gets \mathbf{G}_i \cdot \mathbf{G}_j$ -\State $Compute deformation gradient F \gets \frac{\partial x}{\partial X}$ -\State $Compute current covariant base vectors \mathbf{g}_i \gets F \mathbf{G}_i = \frac{\partial x}{\partial \theta^i} \text{ and current metric } g_{ij} \gets \mathbf{g}_i \cdot \mathbf{g}_j$ -\State $Compute convected Green-Lagrange strain components E_{ij} \gets \frac{1}{2} (g_{ij} - G_{ij})$ -\Return $E_{ij}, g_{ij}, G_{ij}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.62, p. 1; Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf, Sec. 2.12, pp. 1–2_ - - -## 4. Known Pitfalls - -- **Confusing Convected Coordinate Rates with Corotational Objective Rates**: Assuming the convected rate of Kirchhoff stress \tau^{\nabla c} is identical to corotational Jaumann or Green-Naghdi rates. The convected rate directly differentiates tensor components with respect to time in body-fitted convected coordinates, naturally incorporating metric stretch rates rather than rigid-body rotations alone. _(Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Sec. 4.3 & App. A.3, pp. 23–25, 34; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, p. 779)_ -- **Metric Singularities from Severe Grid Distortion**: Evaluating convected metric components g_{ij} = \mathbf{g}_i \cdot \mathbf{g}_j on highly distorted or self-intersecting curvilinear coordinates causes the metric determinant g = \det(g_{ij}) to approach zero or turn negative, invalidating strain and volume integrals. _(Source: Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Sec. 2.10, p. 1; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 3.2.6, p. 83)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf -- Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/kinematics-corotational-update.md b/packages/akms/src/akms/_bundled/global_nodes/kinematics-corotational-update.md deleted file mode 100644 index d047bb5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/kinematics-corotational-update.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: kinematics-corotational-update -title: Corotational Stress Update Algorithms -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- corotational -- hughes-winget -status: established -confidence: 0.9 -source: hybrid -edges: -- to: kinematics-objective-rates - type: requires - weight: 1.0 -- to: kinematics-velocity-gradient - type: requires - weight: 0.9 -- to: kinematics-polar-decomposition - type: requires - weight: 0.8 -- to: plasticity-general-return-mapping - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Corotational Stress Update Algorithms - -## Summary - -Corotational stress update algorithms integrate rate-type constitutive equations under large finite rotations by transforming stress and internal state variables into a corotating reference frame. By applying an incrementally objective proper orthogonal rotation operator (such as the Hughes-Winget midpoint formula), these algorithms isolate rigid-body rotation from material stretching, preventing spurious stress generation during pure rotational motion. - -## 1. Core Concept - -In finite-strain solid mechanics, rate-type constitutive equations require integration schemes that maintain incremental objectivity under large rigid-body rotations. Standard forward Euler integration fails under finite rotations, producing unphysical stress oscillations. Corotational update algorithms overcome this by factorizing incremental motion into a rigid rotation followed or preceded by material stretching. First, the stress and internal state variables from the previous step are rotated into a corotating frame via a proper orthogonal rotation matrix Q. Second, a standard small-strain constitutive update or return-mapping algorithm computes stress increments from the midpoint rate-of-stretching tensor. Finally, updated stresses are back-rotated or stored in the current spatial configuration. - -## 2. Mathematical Formulation - -**Hughes-Winget Midpoint Incremental Rotation Operator** -$$ -Q = \left(I - \frac{1}{2} \omega\right)^{-1} \left(I + \frac{1}{2} \omega\right) -$$ -_Source: Hughes and Winget - 1980 - Finite rotation effects in numerical integration of rate constitutive equations arising in large‐def.pdf, Eqs. 10 & 13, p. 1864; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Prop. 5.4, p. 24_ - -**Rotated Stress Predictor Transformation** -$$ -\bar{\sigma}_{n+1} = Q \sigma_n Q^T, \quad \bar{\alpha}_{n+1} = Q \alpha_n Q^T -$$ -_Source: Hughes and Winget - 1980 - Finite rotation effects in numerical integration of rate constitutive equations arising in large‐def.pdf, Eqs. 11–12, p. 1864; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Def. 5.10, p. 24_ - -**Midpoint Strain Increment and Stress Update** -$$ -\gamma = \frac{1}{2}\left(G + G^T\right), \quad \Delta \sigma = c : \gamma, \quad \sigma_{n+1} = \bar{\sigma}_{n+1} + \Delta \sigma -$$ -_Source: Hughes and Winget - 1980 - Finite rotation effects in numerical integration of rate constitutive equations arising in large‐def.pdf, Eqs. 9 & 11–14, p. 1864; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Alg. 1, p. 25_ - -**Explicit Closed-Form Vector Rotation Expression** -$$ -Q = I + \frac{\omega_m}{1 + \frac{1}{4} \theta_m \cdot \theta_m} \left(I + \frac{1}{2} \omega_m\right) -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.4, Eq. 12.86, p. 417; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 9.5.18, Eq. 9.5.56, p. 556_ - -**Notation:** -{'G': 'Spatial gradient of the displacement increment evaluated at midpoint configuration.', '\\gamma': 'Symmetric midpoint strain increment tensor.', '\\omega': 'Skew-symmetric midpoint spin increment tensor.', 'Q': 'Proper orthogonal rotation tensor (Q^T Q = I).', '\\sigma_n, \\sigma_{n+1}': 'Cauchy stress tensor at step n and step n+1.', '\\bar{\\sigma}_{n+1}': 'Stress tensor rotated by Q prior to constitutive integration.', '\\alpha_n, \\bar{\\alpha}_{n+1}': 'Vector/tensor of material internal state variables before and after rotation.'} - - -## 3. Algorithmic Implementation - -**Hughes-Winget Corotational Stress Update Algorithm** -$$ -\begin{algorithmic} -\State $Given current configuration x_n, displacement increment \Delta u, Cauchy stress \sigma_n, and state variables \alpha_n$ -\State $Compute midpoint displacement gradient G \gets \frac{\partial \Delta u}{\partial x_{n+1/2}}$ -\State $Compute midpoint strain increment \gamma \gets \frac{1}{2}(G + G^T) \text{ and spin increment } \omega \gets \frac{1}{2}(G - G^T)$ -\State $Compute orthogonal incremental rotation Q \gets \left(I - \frac{1}{2}\omega\right)^{-1}\left(I + \frac{1}{2}\omega\right)$ -\State $Rotate stress and state variables: \bar{\sigma} \gets Q \sigma_n Q^T \text{ and } \bar{\alpha} \gets Q \alpha_n Q^T$ -\State $Evaluate small-strain constitutive update using \gamma, \bar{\sigma}, \bar{\alpha} \text{ to obtain stress increment } \Delta \sigma$ -\State $Update Cauchy stress \sigma_{n+1} \gets \bar{\sigma} + \Delta \sigma$ -\Return $\sigma_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Hughes and Winget - 1980 - Finite rotation effects in numerical integration of rate constitutive equations arising in large‐def.pdf, Eqs. 11–14, p. 1864; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Alg. 1, p. 25_ - - -## 4. Known Pitfalls - -- **Spurious Straining Under Finite Rigid-Body Rotations**: Integrating rate constitutive equations without proper incremental rotation neutrality causes false stress generation under pure rigid-body rotation. Mitigation: Use incrementally objective rotation operators, such as the Hughes-Winget midpoint rotation Q = (I - 1/2 \omega)^{-1}(I + 1/2 \omega), which guarantees exact energy conservation and zero stress updates during rigid motions. _(Source: Hughes and Winget - 1980 - Finite rotation effects in numerical integration of rate constitutive equations arising in large‐def.pdf, pp. 1864–1865; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.4, pp. 415–417)_ -- **Kinematic Coupling Errors Under Combined Large Stretch and Rotation**: Assuming constant velocity gradients over a finite time step induces kinematic coupling between stretching and rotation in midpoint corotational updates when rotation increments are large (\theta > 30^\circ). Mitigation: Sub-increment large time steps or use strongly objective rate-of-stretching expansions. _(Source: Rashid - 1993 - Incremental kinematics for finite element applications.pdf, Sec. 4, pp. 3947–3948; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.4, p. 417)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Hughes and Winget - 1980 - Finite rotation effects in numerical integration of rate constitutive equations arising in large‐def.pdf -- Rashid - 1993 - Incremental kinematics for finite element applications.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/kinematics-lie-derivative.md b/packages/akms/src/akms/_bundled/global_nodes/kinematics-lie-derivative.md deleted file mode 100644 index 16a221a..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/kinematics-lie-derivative.md +++ /dev/null @@ -1,229 +0,0 @@ ---- -id: kinematics-lie-derivative -title: Lie Derivative & Connection to Objective Rates -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- lie-derivative -- objectivity -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: stress-push-forward-pull-back - type: requires - weight: 1.0 - note: Lie derivative is the chain pull-back -> d/dt -> push-forward -- to: kinematics-objective-rates - type: refines - weight: 1.0 - note: Lie derivative is the unifying framework — Truesdell, Oldroyd, Cotter-Rivlin are Lie derivatives of kinetic / kinematic - tensors -- to: stress-cauchy-kirchhoff - type: feeds-into - weight: 1.0 - note: $\mathcal{L}_v\boldsymbol{\tau}=\mathbf{F}\dot{\mathbf{S}}\mathbf{F}^T$ links Lagrangian PK2 rate to spatial Kirchhoff - rate -- to: kinematics-velocity-gradient - type: feeds-into - weight: 0.8 - note: $\mathcal{L}_v\,\mathbf{g}=2\mathbf{D}$ recovers rate-of-deformation as Lie of metric -context_size: medium -reading_priority: full -load_with: -- kinematics-objective-rates -- stress-push-forward-pull-back -content_ref: null -akms_schema: v2 ---- - -# Lie Derivative & Connection to Objective Rates - -## Summary -The Lie derivative of a tensor field $\mathbf{T}$ along the spatial velocity field $\mathbf{v}$ is $\mathcal{L}_v\mathbf{T}=\phi_*\!\left(\frac{D}{Dt}\,\phi^*(\mathbf{T})\right)$ — pull $\mathbf{T}$ back to the reference, take its material time derivative there, then push forward to the current configuration. The construction is intrinsically objective: $\mathcal{L}_v$ commutes with arbitrary push-forward by an outer rigid rotation. For kinetic (contravariant-contravariant) tensors $\mathcal{L}_v\boldsymbol{\tau}=\mathbf{F}\dot{\mathbf{S}}\mathbf{F}^T=\dot{\boldsymbol{\tau}}-\mathbf{L}\boldsymbol{\tau}-\boldsymbol{\tau}\mathbf{L}^T$ (Oldroyd / convected of Kirchhoff stress; equivalently the Truesdell rate of $\boldsymbol{\sigma}$ scaled by $J$). For kinematic (covariant-covariant) tensors the rule flips: $\mathcal{L}_v\mathbf{g}=\mathbf{F}^{-T}\dot{\mathbf{C}}\mathbf{F}^{-1}=2\mathbf{D}$ recovers the rate-of-deformation as the Lie derivative of the spatial metric. The Jaumann rate is NOT a Lie derivative — it differs by a symmetric correction $\mathbf{D}\boldsymbol{\sigma}+\boldsymbol{\sigma}\mathbf{D}$ that produces the simple-shear oscillation pathology (`kinematics-objective-rates`). - - -## 1. Core Concept -The Lie derivative is the geometric notion of "rate" on a manifold without privileged coordinates: take the field, transport it back via the inverse flow, differentiate in the fixed reference, transport forward. For a continuum body the inverse flow is the inverse motion $\boldsymbol{\phi}^{-1}$, the differentiation is the material time derivative, and the resulting Lie derivative is automatically frame-indifferent. The catch is that "transport" depends on the variance of the tensor — kinetic tensors transport with $\mathbf{F}\bullet\mathbf{F}^T$, kinematic tensors with $\mathbf{F}^{-T}\bullet\mathbf{F}^{-1}$ — so the same word "Lie derivative" gives different formulas for different tensor types. The Lie derivative of stress is the Truesdell / Oldroyd rate; the Lie derivative of strain is the Cotter-Rivlin rate; the Lie derivative of the metric is twice the rate-of-deformation. This unifies the zoo of objective rates: each is the Lie derivative of a specific tensor variant. The Jaumann rate stands apart because it uses spin $\mathbf{W}$ rather than the full velocity gradient $\mathbf{L}$ for transport, making it a "partial" Lie derivative whose stress-update behaviour is famously pathological under finite shear. - - -## 2. Mathematical Formulation -Throughout, $\boldsymbol{\phi}$ is the motion, $\phi_*,\phi^*$ are push-forward / pull-back along $\boldsymbol{\phi}$. $\mathbf{F}=\nabla_0\boldsymbol{\phi}$. Time derivatives are material: $D/Dt\,(\bullet)|_{\mathbf{X}}$. Symbols below distinguish kinetic / kinematic rules. - - -**Definition:** - -$$ -\mathcal{L}_v\,\mathbf{T} = \phi_*\!\left(\frac{D}{Dt}\,\phi^*(\mathbf{T})\right) -$$ - -where Pull-back, time derivative, push-forward - -**Lie of kinetic tensors (push-forward = $\mathbf{F}\bullet\mathbf{F}^T$):** - -$$ -\mathcal{L}_v\,\boldsymbol{\tau} -= \mathbf{F}\,\frac{D}{Dt}(\mathbf{F}^{-1}\boldsymbol{\tau}\mathbf{F}^{-T})\,\mathbf{F}^T -= \mathbf{F}\,\dot{\mathbf{S}}\,\mathbf{F}^T -$$ - -where Equivalent to Oldroyd rate of Kirchhoff stress - -**Spatial expansion of kinetic Lie derivative:** - -$$ -\mathcal{L}_v\,\boldsymbol{\tau} -= \dot{\boldsymbol{\tau}} - \mathbf{L}\,\boldsymbol{\tau} - \boldsymbol{\tau}\,\mathbf{L}^T -$$ - -where Convective rate; relates to Truesdell rate of Cauchy stress via $\mathcal{L}_v\boldsymbol{\tau}=J\boldsymbol{\sigma}^{\nabla T}$ - -**Lie of kinematic tensors (push-forward = $\mathbf{F}^{-T}\bullet\mathbf{F}^{-1}$):** - -$$ -\mathcal{L}_v\,\mathbf{g} -= \mathbf{F}^{-T}\,\frac{D}{Dt}(\mathbf{F}^T\mathbf{g}\mathbf{F})\,\mathbf{F}^{-1} -= \mathbf{F}^{-T}\,\dot{\mathbf{C}}\,\mathbf{F}^{-1} -= 2\mathbf{D} -$$ - -where Lie derivative of spatial metric = $2\mathbf{D}$ - -**Cotter-Rivlin rate (Lie derivative of covariant tensor):** - -$$ -\mathcal{L}_v^{cov}\,\boldsymbol{\sigma}^{cov} -= \dot{\boldsymbol{\sigma}}^{cov} + \mathbf{L}^T\,\boldsymbol{\sigma}^{cov} + \boldsymbol{\sigma}^{cov}\,\mathbf{L} -$$ - -where Lie of covariant stress component, used when stress is treated as covariant rather than contravariant - -**Decomposition $\mathcal{L}_v = \partial_t + \mathcal{L}_{\mathbf{v},\mathrm{spatial}}$:** - -$$ -\mathcal{L}_v\,\boldsymbol{\tau} -= \frac{\partial \boldsymbol{\tau}}{\partial t}\bigg|_{\mathbf{x}} + \mathbf{v}\cdot\nabla\boldsymbol{\tau} - - \mathbf{L}\,\boldsymbol{\tau} - \boldsymbol{\tau}\,\mathbf{L}^T -$$ - -where Eulerian form: local time derivative + advective + tensorial transport - -**Relation to Jaumann (NOT a pure Lie derivative):** - -$$ -\boldsymbol{\sigma}^{\nabla J} -= \mathcal{L}_v\,\boldsymbol{\sigma} + \mathbf{D}\,\boldsymbol{\sigma} + \boldsymbol{\sigma}\,\mathbf{D} - - \boldsymbol{\sigma}\,\mathrm{tr}\,\mathbf{D} -$$ - -where Jaumann = Truesdell + symmetric corrections; NOT a Lie derivative — explains shear-oscillation pathology - -**Lie derivative chain identity:** - -$$ -\frac{D}{Dt}\,\phi^*(\mathbf{T}) = \phi^*(\mathcal{L}_v\,\mathbf{T}) -$$ - -where Pulled-back time derivative of $\mathcal{L}_v\mathbf{T}$ equals time derivative of pulled-back $\mathbf{T}$ - -**Time integration in Lagrangian frame:** - -$$ -\int_0^t \mathcal{L}_v\,\boldsymbol{\tau}\,d\tau = \mathbf{F}(t)\,(\mathbf{S}(t)-\mathbf{S}(0))\,\mathbf{F}(t)^T -$$ - -where Path-independent integration: integrating Lie rate gives the difference of pulled-back stresses pushed forward - -**Notation:** - -- $\mathcal{L}_v$ — Lie derivative along the spatial velocity field $\mathbf{v}$ -- $\phi_*,\phi^*$ — Push-forward / pull-back operators of the motion $\boldsymbol{\phi}$ -- $\boldsymbol{\tau},\mathbf{S}$ — Kirchhoff and PK2 stress (`stress-piola-kirchhoff`, `stress-cauchy-kirchhoff`) -- $\mathbf{g}$ — Spatial metric tensor (= $\mathbf{I}$ in Euclidean space) -- $\mathbf{C}$ — Right Cauchy-Green tensor -- $\mathbf{D},\mathbf{L}$ — Rate-of-deformation, spatial velocity gradient -- $\boldsymbol{\sigma}^{\nabla J},\boldsymbol{\sigma}^{\nabla T}$ — Jaumann / Truesdell rates of Cauchy stress -- $D/Dt|_{\mathbf{X}}$ — Material time derivative (holding $\mathbf{X}$ fixed) - - -## 3. Algorithmic Implementation -**Algorithm: Compute $\mathcal{L}_v\boldsymbol{\tau}$ via Pull-Back/Push-Forward Chain** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \boldsymbol{\tau}_n,\boldsymbol{\tau}_{n+1},\,\mathbf{F}_n,\,\mathbf{F}_{n+1},\,\Delta t$ -\State $\mathbf{S}_n \gets \mathbf{F}_n^{-1}\,\boldsymbol{\tau}_n\,\mathbf{F}_n^{-T}$ -\State $\mathbf{S}_{n+1} \gets \mathbf{F}_{n+1}^{-1}\,\boldsymbol{\tau}_{n+1}\,\mathbf{F}_{n+1}^{-T}$ -\State $\dot{\mathbf{S}} \gets (\mathbf{S}_{n+1}-\mathbf{S}_n)/\Delta t$ -\State $\mathcal{L}_v\,\boldsymbol{\tau} \gets \mathbf{F}_{n+1}\,\dot{\mathbf{S}}\,\mathbf{F}_{n+1}^T$ -\Return $\mathcal{L}_v\,\boldsymbol{\tau}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Use as a unit test for spatial-form Lie / Truesdell implementations: this chain construction must match $\dot{\boldsymbol{\tau}}-\mathbf{L}\boldsymbol{\tau}-\boldsymbol{\tau}\mathbf{L}^T$ to round-off. In production prefer the spatial form (one matrix algebra rather than four pull-backs / push-forwards), but keep the chain routine for diagnostics. Cache $\mathbf{F}_n^{-1}$ between steps to avoid recomputing the previous step's inverse. - - -**Algorithm: Verify $\mathcal{L}_v\,\mathbf{g}=2\mathbf{D}$** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{F},\dot{\mathbf{F}},\Delta t$ -\State $\mathbf{C} \gets \mathbf{F}^T\mathbf{F},\;\dot{\mathbf{C}} \gets \dot{\mathbf{F}}^T\mathbf{F} + \mathbf{F}^T\dot{\mathbf{F}}$ -\State $\mathcal{L}_v\,\mathbf{g} \gets \mathbf{F}^{-T}\,\dot{\mathbf{C}}\,\mathbf{F}^{-1}$ -\State $2\mathbf{D} \gets \mathbf{L} + \mathbf{L}^T \;\text{with } \mathbf{L} = \dot{\mathbf{F}}\mathbf{F}^{-1}$ -\State $\text{assert} \;\|\mathcal{L}_v\,\mathbf{g} - 2\mathbf{D}\|/\|\mathbf{D}\| < 10^{-12}$ -\Return $\mathcal{L}_v\,\mathbf{g}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Diagnostic / regression test, not a production routine. Run on at least one Gauss point to confirm the kinematic Lie derivative is implemented correctly — failures usually reveal sign errors or wrong index ordering in the kinematic push-forward / pull-back rule. - - -**Algorithm: Convert Between Spatial Lie Form and Truesdell-Cauchy Form** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathcal{L}_v\,\boldsymbol{\tau},\,J,\,\mathrm{tr}\,\mathbf{D}$ -\State $\boldsymbol{\sigma}^{\nabla T} \gets J^{-1}\,\mathcal{L}_v\,\boldsymbol{\tau} - \boldsymbol{\sigma}\,\mathrm{tr}\,\mathbf{D} \;\;(\text{equivalently}\;= \dot{\boldsymbol{\sigma}} - \mathbf{L}\boldsymbol{\sigma} - \boldsymbol{\sigma}\mathbf{L}^T + \boldsymbol{\sigma}\,\mathrm{tr}\,\mathbf{L})$ -\Return $\boldsymbol{\sigma}^{\nabla T}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Keep both forms available so the user code can choose either Kirchhoff Lie or Cauchy Truesdell at the API. Truesdell of $\boldsymbol{\sigma}$ has the volumetric correction baked in; Lie of $\boldsymbol{\tau}$ does not. The conversion is one division by $J$ and one trace contraction. - - - -## 4. Known Pitfalls -**Confusing kinetic and kinematic Lie derivatives:** $\mathcal{L}_v\,\boldsymbol{\tau}=\mathbf{F}\dot{\mathbf{S}}\mathbf{F}^T$ uses the kinetic push-forward; $\mathcal{L}_v\,\mathbf{g}=\mathbf{F}^{-T}\dot{\mathbf{C}}\mathbf{F}^{-1}$ uses the kinematic. Applying the kinematic rule to a kinetic tensor (a common slip when adapting metric formulas) silently destroys symmetry / power conjugacy and produces wrong stress rates. - - -**Forgetting that Lie derivative depends on tensor variance:** "Lie derivative" is shorthand for a family of operators indexed by tensor variance. Stating "$\mathcal{L}_v\mathbf{T}$" without specifying whether $\mathbf{T}$ is kinetic or kinematic leaves the formula ambiguous. Document the variance at every API boundary; a tensor stored as $T_{ij}$ may be either contravariant or covariant component-wise, and the choice determines the push-forward rule. - - -**Mistaking Lie of metric for $\mathbf{L}$:** $\mathcal{L}_v\mathbf{g}=2\mathbf{D}$, NOT $\mathbf{L}$. The Lie derivative of the spatial metric is the SYMMETRIC rate-of-deformation; the velocity gradient $\mathbf{L}$ is generally asymmetric. Using $\mathbf{L}$ in place of $2\mathbf{D}$ in a Lie-derivative-based formulation introduces spurious skew contributions. - - -**Assuming all objective rates are Lie derivatives:** Truesdell, Oldroyd, Cotter-Rivlin, Lie of $\boldsymbol{\tau}$: all are pure Lie derivatives. Jaumann is NOT — it differs from Lie by symmetric $\mathbf{D}\boldsymbol{\sigma}+\boldsymbol{\sigma}\mathbf{D}$ corrections. Green-Naghdi is also NOT a Lie derivative (it uses the polar rotation rate, not full $\mathbf{L}$). Treating all four as members of the same family produces tangents off by symmetric corrections. - - -**Implementing $\dot{\boldsymbol{\sigma}}+\boldsymbol{\sigma}\,\mathrm{tr}\,\mathbf{L}$ as if Lie:** $\dot{\boldsymbol{\sigma}}-\mathbf{L}\boldsymbol{\sigma}-\boldsymbol{\sigma}\mathbf{L}^T+\boldsymbol{\sigma}\,\mathrm{tr}\,\mathbf{L}$ is the Truesdell rate of CAUCHY stress, NOT a pure Lie derivative. The Lie of Kirchhoff is $\dot{\boldsymbol{\tau}}-\mathbf{L}\boldsymbol{\tau}-\boldsymbol{\tau}\mathbf{L}^T$ (no trace term). The two are equivalent up to a $J$ rescaling and the trace correction; mixing them produces a residual off by $\boldsymbol{\sigma}\,\mathrm{tr}\,\mathbf{D}$. - - -**Path-dependence under finite-difference $\mathbf{S}$:** Computing $\dot{\mathbf{S}}\approx(\mathbf{S}_{n+1}-\mathbf{S}_n)/\Delta t$ and pushing forward to $\mathcal{L}_v\boldsymbol{\tau}=\mathbf{F}_{n+1}\dot{\mathbf{S}}\mathbf{F}_{n+1}^T$ produces a result that depends on the choice of $\mathbf{F}_{n+1}$ vs $\mathbf{F}_{n+1/2}$ for the push-forward. Use the mid-point $\mathbf{F}_{n+1/2}$ for second-order accuracy; using $\mathbf{F}_{n+1}$ degrades to first order. - - -**Missing the convective term in spatial expansion:** $\mathcal{L}_v\boldsymbol{\tau}=\dot{\boldsymbol{\tau}}-\mathbf{L}\boldsymbol{\tau}-\boldsymbol{\tau}\mathbf{L}^T$. The two transport terms are essential — dropping either one (a common slip) makes the rate non-objective and reproduces the Jaumann pathology in disguise. Always include both $\mathbf{L}\boldsymbol{\tau}$ and $\boldsymbol{\tau}\mathbf{L}^T$. - - -## 5. References -- Belytschko, Liu, Moran & Elkhodary (2014) — Nonlinear Finite Elements for Continua and Structures, 2nd ed. (Lie derivative, Box 5.17, relations to Jaumann / Truesdell rates) -- Holzapfel (2000) — Nonlinear Solid Mechanics (Lie derivative of contravariant / covariant tensors, convected rates, Cotter-Rivlin) -- Marsden & Hughes (1983) — Mathematical Foundations of Elasticity (geometric formulation of Lie derivatives in continuum mechanics) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/kinematics-logarithmic-strain.md b/packages/akms/src/akms/_bundled/global_nodes/kinematics-logarithmic-strain.md deleted file mode 100644 index 6f414cd..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/kinematics-logarithmic-strain.md +++ /dev/null @@ -1,248 +0,0 @@ ---- -id: kinematics-logarithmic-strain -title: Logarithmic (Hencky) Strain -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- hencky-strain -- log-strain -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: kinematics-polar-decomposition - type: requires - weight: 1.0 - note: $\mathbf{E}_{\log}=\ln\mathbf{U}$ depends on the right stretch from polar decomposition -- to: tensor-isotropic-functions - type: requires - weight: 1.0 - note: Spectral evaluation of $\ln\mathbf{C}$ via $\sum_a\ln\lambda_a\,\mathbf{P}_a$ -- to: kinematics-strain-tensors - type: refines - weight: 0.9 - note: Hencky strain is the $m=0$ member of the Seth-Hill family -- to: kinematics-velocity-gradient - type: feeds-into - weight: 0.6 - note: Rate $\dot{\mathbf{E}}_{\log}$ equals $\mathbf{D}$ only for coaxial flows -context_size: medium -reading_priority: full -load_with: -- kinematics-polar-decomposition -- tensor-isotropic-functions -content_ref: null -akms_schema: v2 ---- - -# Logarithmic (Hencky) Strain - -## Summary -The logarithmic (Hencky) strain $\mathbf{E}_{\log}=\ln\mathbf{U}=\tfrac12\ln\mathbf{C}$ is the natural finite-strain extension of the small-strain tensor: it has additive structure on the principal axes and reduces exactly to $\boldsymbol{\varepsilon}=\tfrac12(\nabla\mathbf{u}+\nabla\mathbf{u}^T)$ in the small-strain limit. Spectrally $\mathbf{E}_{\log}=\sum_a\ln\lambda_a\,\mathbf{N}_a\otimes\mathbf{N}_a$ where $\lambda_a$ are principal stretches. Its rate equals the rate-of-deformation $\mathbf{D}$ ONLY for coaxial flows (no rotation of principal axes); under non-coaxial loading $\dot{\mathbf{E}}_{\log}\ne\mathbf{D}$ and the integral of $\mathbf{D}$ is path-dependent while $\mathbf{E}_{\log}$ is path-independent. The Miehe-Apel-Lambrecht (2002) framework wraps a small-strain plasticity model with geometric pre/post-processors $\mathbb{P}_L=2\,\partial\mathbf{E}_{\log}/\partial\mathbf{C}$ and $\mathbb{L}_L=4\,\partial^2\mathbf{E}_{\log}/\partial\mathbf{C}\partial\mathbf{C}$, evaluated by Carlson-Hoger divided differences with explicit L'Hopital limits at coincident eigenvalues. - - -## 1. Core Concept -Hencky strain has two virtues that make it the strain measure of choice for finite-strain plasticity. (1) Additive structure: principal Hencky strains add under composition of coaxial stretches, $\ln(\lambda_1\lambda_2)=\ln\lambda_1+\ln\lambda_2$, mirroring the additive small-strain calculus that constitutive theories were originally built on. (2) Volume-deviatoric decoupling: $\mathrm{tr}\,\mathbf{E}_{\log}=\ln J$ is exactly the logarithmic volume change, so the deviatoric Hencky strain $\mathbf{E}_{\log}^{\mathrm{dev}}=\mathbf{E}_{\log}-\tfrac13(\ln J)\mathbf{I}$ is a clean shape-change measure orthogonal to volume change. The price is that the decomposition through the eigenvalues of $\mathbf{C}$ (or $\mathbf{U}$) is required, with all the robustness machinery of `tensor-spectral-decomposition` and `tensor-isotropic-functions`. The Miehe et al. modular wrapper makes the price worthwhile: any small-strain plasticity model can be promoted to finite strain by sandwiching it between $\mathbb{P}_L$ and $\mathbb{L}_L$. - - -## 2. Mathematical Formulation -Throughout, $\mathbf{C}=\mathbf{F}^T\mathbf{F}$ is symmetric positive-definite (so $\det\mathbf{F}>0$). $\mathbf{U}=\sqrt{\mathbf{C}}$ is the right stretch from the polar decomposition. $\lambda_a$ are principal stretches (eigenvalues of $\mathbf{U}$); $\mathbf{N}_a$ material principal directions; $\mathbf{P}_a=\mathbf{N}_a\otimes\mathbf{N}_a$ eigenprojections. - - -**Definition (material / spatial):** - -$$ -\mathbf{E}_{\log} = \ln\mathbf{U} = \tfrac{1}{2}\ln\mathbf{C},\qquad -\mathbf{e}_{\log} = \ln\mathbf{V} = \tfrac{1}{2}\ln\mathbf{b} -$$ - -where Material (Lagrangian) and spatial (Eulerian) versions related by $\mathbf{e}_{\log}=\mathbf{R}\mathbf{E}_{\log}\mathbf{R}^T$ - -**Spectral form:** - -$$ -\mathbf{E}_{\log} -= \sum_{a=1}^{3}\ln\lambda_a\,\mathbf{P}_a -= \tfrac{1}{2}\sum_{a=1}^{3}\ln(\lambda_a^2(\mathbf{C}))\,\mathbf{P}_a(\mathbf{C}) -$$ - -where $\lambda_a(\mathbf{C})=\lambda_a^2(\mathbf{U})$ - -**Volumetric / deviatoric decoupling:** - -$$ -\mathrm{tr}\,\mathbf{E}_{\log} = \ln J,\qquad -\mathbf{E}_{\log}^{\mathrm{dev}} = \mathbf{E}_{\log} - \tfrac{1}{3}\,(\ln J)\,\mathbf{I} -$$ - -where Deviatoric Hencky strain measures pure shape change; trace gives logarithmic volume strain - -**Small-strain limit:** - -$$ -\mathbf{E}_{\log} = \boldsymbol{\varepsilon} + \mathcal{O}(\|\mathbf{H}\|^2),\qquad -\boldsymbol{\varepsilon} = \tfrac{1}{2}(\nabla\mathbf{u} + \nabla\mathbf{u}^T) -$$ - -where All Seth-Hill measures coincide in $\mathbf{H}\to 0$; Hencky uniquely preserves the additive structure - -**Inverse: recovery of $\mathbf{C}$:** - -$$ -\mathbf{C} = \exp(2\,\mathbf{E}_{\log}) = \sum_{a=1}^{3}\exp(2\,e_a)\,\mathbf{P}_a,\qquad -e_a = \ln\lambda_a -$$ - -where Exponential map: takes Hencky strain back to deformation tensor - -**Rate vs $\mathbf{D}$ — coaxial only:** - -$$ -\dot{\mathbf{E}}_{\log} = \mathbf{D} \;\Leftrightarrow\; -\dot{\mathbf{N}}_a = \mathbf{0}\;\text{(coaxial flow)} -$$ - -where For non-coaxial flow $\dot{\mathbf{E}}_{\log}\ne\mathbf{D}$ and the equality fails by spin-coupling terms - -**Path independence:** - -$$ -\int_0^t \dot{\mathbf{E}}_{\log}\,d\tau = \mathbf{E}_{\log}(t)\;\;\text{(path-independent)},\qquad -\int_0^t \mathbf{D}\,d\tau \ne \mathbf{E}_{\log}(t)\;\;\text{(path-dependent)} -$$ - -where Logarithmic strain integrates to a state function; rate-of-deformation does not - -**Miehe et al. transformation tensors:** - -$$ -\mathbb{P}_L = 2\,\frac{\partial \mathbf{E}_{\log}}{\partial \mathbf{C}},\qquad -\mathbb{L}_L = 4\,\frac{\partial^2 \mathbf{E}_{\log}}{\partial \mathbf{C}\partial\mathbf{C}} -$$ - -where Pre/post-processor 4th- / 6th-order tensors of the modular log-strain framework (`tensor-isotropic-functions`) - -**Carlson-Hoger derivative:** - -$$ -\mathbb{P}_L = \sum_{i=1}^{3} d_i\,\mathbf{P}_i\bar\otimes\mathbf{P}_i - + 2\sum_{i\ne j}\,\upsilon_{ij}\,\mathbf{P}_i\bar\otimes\mathbf{P}_j, -\qquad -d_i = \lambda_i^{-2},\; -\upsilon_{ij} = \frac{e_i - e_j}{\lambda_i^2 - \lambda_j^2} -$$ - -where Eigenvalues of $\mathbf{C}$ are $\lambda_i^2$; divided differences become $\tfrac{1}{2}d_i$ at coincident eigenvalues (`tensor-derivatives-tensors`) - -**Notation:** - -- $\mathbf{E}_{\log}$ — Lagrangian Hencky strain, $\ln\mathbf{U}=\tfrac12\ln\mathbf{C}$ -- $\mathbf{e}_{\log}$ — Eulerian Hencky strain, $\ln\mathbf{V}=\tfrac12\ln\mathbf{b}$ -- $\mathbf{U}$ — Right stretch (`kinematics-polar-decomposition`) -- $\mathbf{C}$ — Right Cauchy-Green tensor, $\mathbf{C}=\mathbf{F}^T\mathbf{F}=\mathbf{U}^2$ -- $\lambda_a$ — Principal stretches -- $e_a$ — Logarithmic eigenstrains, $e_a=\ln\lambda_a$ -- $\mathbf{P}_a$ — Eigenprojections, $\mathbf{P}_a=\mathbf{N}_a\otimes\mathbf{N}_a$ -- $\mathbf{D}$ — Rate-of-deformation (`kinematics-velocity-gradient`) -- $\mathbb{P}_L,\mathbb{L}_L$ — Lagrangian transformation tensors of Miehe et al. 2002 -- $J$ — Jacobian, $J=\det\mathbf{F}$ - - -## 3. Algorithmic Implementation -**Algorithm: Hencky Strain via Spectral Decomposition of $\mathbf{C}$** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{C}\in\mathbb{R}^{3\times 3}_{\mathrm{sym},\mathrm{pd}},\,\text{tol }\tau$ -\State $\{\lambda_i^2, \mathbf{N}_i\}_{i=1,2,3} \gets \mathrm{eig}(\mathbf{C}) \;\text{(closed-form Lode-angle)}$ -\For{$i = 1,2,3$} -\If{$\lambda_i^2 < \lambda_{\min}^2$} -\State $\text{abort: log strain undefined for non-positive eigenvalues}$ -\EndIf -\State $e_i \gets \tfrac{1}{2}\ln(\lambda_i^2)$ -\EndFor -\State $\mathbf{E}_{\log} \gets \sum_{i=1}^{3} e_i\,\mathbf{N}_i\otimes\mathbf{N}_i$ -\Return $\mathbf{E}_{\log}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Reuse the closed-form Lode-angle eigensolver. Use $\lambda_{\min}=10^{-3}$ in double precision; below that the log saturates and the constitutive model is outside its calibration range anyway. For mass production, fuse with the constitutive update in one kernel so the eigendecomposition is computed once and reused for both $\mathbf{E}_{\log}$ and $\mathbb{P}_L$. - - -**Algorithm: Tangent $\mathbb{P}_L$ via Carlson-Hoger Divided Differences** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{C},\,\{\lambda_i^2,\mathbf{N}_i\},\,e_i,\,\text{tol }\tau$ -\For{$i = 1,2,3$} -\State $d_i \gets (\lambda_i^2)^{-1}$ -\State $\mathbf{P}_i \gets \mathbf{N}_i\otimes\mathbf{N}_i$ -\EndFor -\For{$i,j = 1,2,3,\;i\ne j$} -\If{$|\lambda_i^2 - \lambda_j^2| > \tau\,(\lambda_i^2 + \lambda_j^2)$} -\State $\upsilon_{ij} \gets (e_i - e_j)/(\lambda_i^2 - \lambda_j^2)$ -\Else -\State $\upsilon_{ij} \gets \tfrac{1}{2}\,d_i \;\text{(L'Hopital limit)}$ -\EndIf -\EndFor -\State $\mathbb{P}_L \gets \sum_i d_i\,\mathbf{P}_i\bar\otimes\mathbf{P}_i + 2\sum_{i\ne j}\upsilon_{ij}\,\mathbf{P}_i\bar\otimes\mathbf{P}_j$ -\Return $\mathbb{P}_L$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Store $\mathbb{P}_L$ in Mandel form ($6\times 6$) so the downstream stress map $\mathbf{S}=\mathbf{T}\colon\mathbb{P}_L$ is a $6$-vector / $6\times 6$ matrix dot product. Use $\tau=10^{-12}$ in double precision; the L'Hopital branch is rare except at exactly biaxial / hydrostatic loading, which are precisely the cases used in verification benchmarks. - - -**Algorithm: Modular Finite-Strain Plasticity Wrapper (Miehe et al. 2002)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{C}_{n+1},\,(\mathbf{E}^p_n,q_n)$ -\State $\mathbf{E}_{\log,n+1} \gets \tfrac{1}{2}\ln\mathbf{C}_{n+1}$ -\State $\mathbb{P}_L \gets 2\,\partial\mathbf{E}_{\log}/\partial\mathbf{C}$ -\State $\mathbf{T}_{n+1},\mathbf{E}^p_{n+1},q_{n+1},\mathbb{E}_{ep} \gets \mathrm{SmallStrainPlasticity}(\mathbf{E}_{\log,n+1},\mathbf{E}^p_n,q_n)$ -\State $\mathbf{S}_{n+1} \gets \mathbf{T}_{n+1}\colon\mathbb{P}_L$ -\State $\mathbb{L}_L \gets 4\,\partial^2 \mathbf{E}_{\log}/\partial\mathbf{C}\partial\mathbf{C}$ -\State $\mathbb{C}^L_{ep} \gets \mathbb{P}_L^T\colon\mathbb{E}_{ep}\colon\mathbb{P}_L + \mathbf{T}_{n+1}\colon\mathbb{L}_L$ -\Return $\mathbf{S}_{n+1},\mathbb{C}^L_{ep},\mathbf{E}^p_{n+1},q_{n+1}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -The wrapper makes any verified small-strain return-mapping (`plasticity-return-mapping`, `plasticity-yield-surfaces`) usable at finite strain with no changes to the constitutive box. Cache the eigendecomposition of $\mathbf{C}_{n+1}$ once; reuse for $\mathbf{E}_{\log}$, $\mathbb{P}_L$, $\mathbb{L}_L$. The geometric correction $\mathbf{T}\colon\mathbb{L}_L$ is essential for quadratic Newton convergence at finite strain — do NOT drop it. - - - -## 4. Known Pitfalls -**Branch-cut at non-positive principal stretches:** $\ln\lambda_a$ is real-valued only for $\lambda_a>0$. Numerical instability (element inversion, severe distortion) can briefly drive $\lambda_a\to 0$ and the spectral $\ln\mathbf{C}$ returns NaN. Detect $\lambda_{\min}<\lambda_{\mathrm{tol}}$ before invoking $\ln$; abort the increment / activate locking remedies / reduce the time step. - - -**$\dot{\mathbf{E}}_{\log}\ne\mathbf{D}$ for non-coaxial flows:** The naive identification $\dot{\mathbf{E}}_{\log}=\mathbf{D}$ is exact only when principal axes do not rotate (coaxial flow). Under simple shear with rotation the two differ by spin-coupling terms and the integral of $\mathbf{D}$ is path-dependent while $\mathbf{E}_{\log}$ is not. Constitutive integrators that use $\mathbf{D}$ as if it were $\dot{\mathbf{E}}_{\log}$ accumulate spurious strain along closed paths — most visible on cyclic shear benchmarks. - - -**Series vs spectral evaluation mismatch:** The Taylor series $\ln\mathbf{C}=\sum_{n\ge 1}(-1)^{n-1}(\mathbf{C}-\mathbf{I})^n/n$ converges only for $\|\mathbf{C}-\mathbf{I}\|<1$ (small / moderate strain). At large strain a truncated series gives a different $\mathbf{E}_{\log}$ than the spectral form, and mixing series for the strain with spectral for the tangent breaks the energy mapping. Use the spectral form everywhere. - - -**Factor of 1/2 confusion between $\ln\mathbf{U}$ and $\tfrac12\ln\mathbf{C}$:** $\mathbf{E}_{\log}=\ln\mathbf{U}=\tfrac12\ln\mathbf{C}$ — equivalent because $\mathbf{C}=\mathbf{U}^2$. Mixing the two conventions in the same code path inserts a factor 2 into the conjugate stress. State the convention explicitly at every wrapper boundary and validate on a uniaxial benchmark where the closed-form analytical answer is known. - - -**Singular Carlson-Hoger divided differences at degenerate eigenvalues:** The divided difference $\upsilon_{ij}=(e_i-e_j)/(\lambda_i^2-\lambda_j^2)$ blows up as $\lambda_i^2\to\lambda_j^2$, even though $\mathbf{E}_{\log}$ remains smooth. Without the L'Hopital substitution $\upsilon_{ii}\gets\tfrac{1}{2}d_i$ the constitutive tangent NaN's at hydrostatic / biaxial states. Trigger the branch with a relative tolerance $|\lambda_i^2-\lambda_j^2|<\tau(\lambda_i^2+\lambda_j^2)$. - - -**Dropping $\mathbf{T}\colon\mathbb{L}_L$ in the Lagrangian tangent:** The tangent $\mathbb{C}^L_{ep}$ has TWO terms: the "constitutive" $\mathbb{P}_L^T\colon\mathbb{E}_{ep}\colon\mathbb{P}_L$ and the "geometric" $\mathbf{T}\colon\mathbb{L}_L$. Dropping the geometric correction (a common simplification in implementation) degrades Newton convergence from quadratic to linear at finite strain and makes path-following solvers stall near limit points. The geometric term vanishes only in the small-strain limit. - - -**Confusing material $\mathbf{E}_{\log}$ with spatial $\mathbf{e}_{\log}$:** $\mathbf{E}_{\log}=\ln\mathbf{U}$ lives on the reference frame; $\mathbf{e}_{\log}=\ln\mathbf{V}$ lives on the current frame; they are related by $\mathbf{e}_{\log}=\mathbf{R}\mathbf{E}_{\log}\mathbf{R}^T$. Plotting the material strain on the deformed mesh (a common output mistake) yields visually plausible but quantitatively wrong distributions — the principal directions are off by the polar rotation $\mathbf{R}$. - - -## 5. References -- Belytschko, Liu, Moran & Elkhodary (2014) — Nonlinear Finite Elements for Continua and Structures, 2nd ed. (Hencky strain definition, additive structure, conjugacy) -- Miehe, Apel, Lambrecht (2002) — Anisotropic additive plasticity in the logarithmic strain space (modular framework, four key transformation equations $\mathbb{P}_L$ and $\mathbb{L}_L$, divided-difference branches) -- Holzapfel (2000) — Nonlinear Solid Mechanics (Hencky strain, principal-stretch decomposition) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/kinematics-motion-deformation-gradient.md b/packages/akms/src/akms/_bundled/global_nodes/kinematics-motion-deformation-gradient.md deleted file mode 100644 index 7156306..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/kinematics-motion-deformation-gradient.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -id: kinematics-motion-deformation-gradient -title: Motion & Deformation Gradient -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- deformation-gradient -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: tensor-index-notation - type: requires - weight: 0.8 - note: $F_{iJ}=\partial x_i/\partial X_J$ uses one spatial (lower-case) and one material (upper-case) index -- to: kinematics-strain-tensors - type: feeds-into - weight: 1.0 - note: All Seth-Hill strains derive from $\mathbf{C}=\mathbf{F}^T\mathbf{F}$ or $\mathbf{b}=\mathbf{F}\mathbf{F}^T$ -- to: kinematics-polar-decomposition - type: feeds-into - weight: 1.0 - note: $\mathbf{F}=\mathbf{R}\mathbf{U}=\mathbf{V}\mathbf{R}$ separates rigid rotation from stretch -- to: kinematics-velocity-gradient - type: feeds-into - weight: 1.0 - note: Spatial velocity gradient $\mathbf{L}=\dot{\mathbf{F}}\mathbf{F}^{-1}$ -- to: fem-tl-b-matrix - type: feeds-into - weight: 0.9 - note: B-matrix builds $\mathbf{F}$ from nodal displacements via shape function gradients -context_size: medium -reading_priority: full -load_with: -- kinematics-strain-tensors -- kinematics-velocity-gradient -content_ref: null -akms_schema: v2 ---- - -# Motion & Deformation Gradient - -## Summary -The motion of a body is the smooth one-parameter family of mappings $\mathbf{x}=\boldsymbol{\phi}(\mathbf{X},t)$ that takes each material point $\mathbf{X}$ in the reference configuration to its current position $\mathbf{x}$. Its material gradient is the deformation gradient $\mathbf{F}=\partial\mathbf{x}/\partial\mathbf{X}$ — an Eulerian-Lagrangian two-point tensor with components $F_{iJ}=\partial x_i/\partial X_J$ (lower-case spatial, upper-case material). $\mathbf{F}$ maps line elements ($d\mathbf{x}=\mathbf{F}\,d\mathbf{X}$), and via Nanson's formula $\mathbf{n}\,da = J\,\mathbf{F}^{-T}\mathbf{n}_0\,dA_0$ it maps oriented areas. The Jacobian $J=\det\mathbf{F}=dv/dV_0=\rho_0/\rho$ is the local volume ratio and must remain strictly positive ($J>0$) to keep the mapping invertible. Rate $\dot{\mathbf{F}}=\mathbf{L}\mathbf{F}$ links to the velocity gradient; in FEM $\mathbf{F}$ is built per element from nodal displacements via the B-matrix. - - -## 1. Core Concept -$\mathbf{F}$ is the central kinematic object in nonlinear solid mechanics. Geometrically it is the linearisation of the motion at a material point: line elements transform linearly via $d\mathbf{x}=\mathbf{F}\,d\mathbf{X}$, areas by Nanson's formula, and volumes by the scalar $J=\det\mathbf{F}$. Because $\mathbf{F}$ has one leg in the reference configuration and one in the current configuration, it is a TWO-POINT tensor — its row index is spatial (lower-case $i$), its column index is material (upper-case $J$) — and operations like push-forward / pull-back, polar decomposition, and the multiplicative split $\mathbf{F}=\mathbf{F}^e\mathbf{F}^p$ all hinge on respecting that asymmetry. In a finite element, $\mathbf{F}$ is reconstructed at each Gauss point from the displacement field $\mathbf{u}=\mathbf{x}-\mathbf{X}$ via shape function gradients ($\mathbf{H}=\partial\mathbf{u}/\partial\mathbf{X}$, $\mathbf{F}=\mathbf{I}+\mathbf{H}$); this construction underlies every TL-FEM weak-form derivation and every B-matrix formulation. - - -## 2. Mathematical Formulation -Reference coordinates $\mathbf{X}$ live in the undeformed body $\Omega_0$, current coordinates $\mathbf{x}$ in $\Omega_t$. The motion is $\mathbf{x}=\boldsymbol{\phi}(\mathbf{X},t)$, smooth in both arguments. Lower-case Latin indices ($i,j,k$) are spatial; upper-case ($I,J,K$) are material; both run over $\{1,2,3\}$. Velocity is $\mathbf{v}(\mathbf{X},t)=\partial\boldsymbol{\phi}/\partial t$. - - -**Motion and deformation gradient:** - -$$ -\mathbf{x} = \boldsymbol{\phi}(\mathbf{X},t),\qquad -\mathbf{F} = \frac{\partial \mathbf{x}}{\partial \mathbf{X}} = \nabla_0\boldsymbol{\phi},\qquad -F_{iJ} = \frac{\partial x_i}{\partial X_J} -$$ - -where Two-point tensor with mixed Eulerian-Lagrangian indices - -**Line, area, and volume transforms:** - -$$ -d\mathbf{x} = \mathbf{F}\cdot d\mathbf{X},\qquad -\mathbf{n}\,da = J\,\mathbf{F}^{-T}\cdot\mathbf{n}_0\,dA_0,\qquad -dv = J\,dV_0 -$$ - -where Nanson's formula for oriented area; $J=\det\mathbf{F}$ for volume - -**Jacobian and admissibility:** - -$$ -J = \det\mathbf{F} = \frac{dv}{dV_0} = \frac{\rho_0}{\rho},\qquad -J > 0 -$$ - -where $J>0$ keeps the mapping one-to-one and orientation-preserving - -**From displacement:** - -$$ -\mathbf{u}(\mathbf{X},t) = \mathbf{x} - \mathbf{X},\qquad -\mathbf{H} = \nabla_0 \mathbf{u} = \frac{\partial \mathbf{u}}{\partial \mathbf{X}},\qquad -\mathbf{F} = \mathbf{I} + \mathbf{H} -$$ - -where $\mathbf{H}$ is the displacement gradient; $\mathbf{F}\to\mathbf{I}$ in the small-strain limit - -**Time rate and velocity gradient:** - -$$ -\dot{\mathbf{F}} = \frac{\partial \mathbf{F}}{\partial t}\bigg|_{\mathbf{X}} = \mathbf{L}\,\mathbf{F},\qquad -\mathbf{L} = \dot{\mathbf{F}}\,\mathbf{F}^{-1} = \nabla \mathbf{v} -$$ - -where $\mathbf{L}$ is the spatial velocity gradient (`kinematics-velocity-gradient`) - -**Inverse and identity:** - -$$ -\mathbf{F}\cdot\mathbf{F}^{-1} = \mathbf{I},\qquad -\mathbf{F}^{-T} = (\mathbf{F}^T)^{-1} = (\mathbf{F}^{-1})^T,\qquad -F^{-1}_{Ji} = \frac{\partial X_J}{\partial x_i} -$$ - -where $\mathbf{F}^{-1}$ is the material gradient of the INVERSE motion $\mathbf{X}=\boldsymbol{\phi}^{-1}(\mathbf{x},t)$ - -**Polar decomposition (referenced):** - -$$ -\mathbf{F} = \mathbf{R}\,\mathbf{U} = \mathbf{V}\,\mathbf{R},\qquad -\mathbf{R}\in SO(3),\; -\mathbf{U}=\mathbf{U}^T\succ 0 -$$ - -where Detail in `kinematics-polar-decomposition` - -**Mass conservation:** - -$$ -\rho_0 = J\,\rho,\qquad -\int_{\Omega_0}\rho_0\,dV_0 = \int_{\Omega_t}\rho\,dv -$$ - -where Trivial consequence of the volume transform - -**Notation:** - -- $\mathbf{X}$ — Reference (Lagrangian) position vector -- $\mathbf{x}$ — Current (Eulerian) position vector -- $\boldsymbol{\phi}$ — Motion mapping, $\mathbf{x}=\boldsymbol{\phi}(\mathbf{X},t)$ -- $\mathbf{F}$ — Deformation gradient, $\mathbf{F}=\partial\mathbf{x}/\partial\mathbf{X}$ -- $F_{iJ}$ — Component, lower-case spatial $i$ and upper-case material $J$ -- $J$ — Jacobian, $J=\det\mathbf{F}>0$ -- $\mathbf{H}$ — Displacement gradient $\mathbf{H}=\nabla_0\mathbf{u}$ -- $\mathbf{u}$ — Displacement field, $\mathbf{u}=\mathbf{x}-\mathbf{X}$ -- $\mathbf{L}$ — Spatial velocity gradient, $\mathbf{L}=\dot{\mathbf{F}}\mathbf{F}^{-1}$ -- $\rho_0,\rho$ — Reference and current mass densities - - -## 3. Algorithmic Implementation -**Algorithm: Compute $\mathbf{F}$ at a Gauss Point from Nodal Displacements** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \{\mathbf{u}_a\}_{a=1}^{n_n},\,\{\partial N_a/\partial \mathbf{X}\}_{a=1}^{n_n} \;\text{at the GP}$ -\State $\mathbf{H} \gets \mathbf{0} \in \mathbb{R}^{3\times 3}$ -\For{$a = 1,\ldots,n_n$} -\For{$i,J = 1,2,3$} -\State $H_{iJ} \mathrel{+}= u_{a,i}\,(\partial N_a/\partial X_J)$ -\EndFor -\EndFor -\State $\mathbf{F} \gets \mathbf{I} + \mathbf{H}$ -\State $J \gets \det\mathbf{F}$ -\If{$J \le J_{\min}$} -\State $\text{trigger element-inversion handler (line search / step bisection / abort)}$ -\EndIf -\Return $\mathbf{F},\,J,\,\mathbf{H}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Implement as a `@ti.func` per Gauss point. Pre-compute $\partial N_a/\partial \mathbf{X}$ once per element at the start of the step (cheap because reference geometry is fixed in TL-FEM). Use `ti.static(range(n_n))` to fully unroll the node loop for fixed-element kernels. Build $\mathbf{F}=\mathbf{I}+\mathbf{H}$ rather than directly summing into $\mathbf{F}$: this avoids massive cancellation at small strain (round-off pitfall). - - -**Algorithm: Closed-Form 3x3 Inverse and Determinant** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{F}\in\mathbb{R}^{3\times 3}$ -\State $\mathrm{cof}_{ij}\mathbf{F} \gets \tfrac{1}{2}\,e_{ikl}\,e_{jmn}\,F_{km}\,F_{ln}$ -\State $J \gets F_{1i}\,(\mathrm{cof}\,\mathbf{F})_{1i} \;\text{(co-factor expansion)}$ -\State $\mathbf{F}^{-1} \gets (\mathrm{cof}\,\mathbf{F})^T / J$ -\Return $J,\,\mathbf{F}^{-1}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Hand-coded $3\times 3$ inverse outperforms `ti.linalg.inverse` (which targets generic dimensions). Reuse the cofactor matrix for $\partial(\det\mathbf{F})/\partial\mathbf{F} = (\det\mathbf{F})\,\mathbf{F}^{-T}$. For TL-FEM the inverse is rarely needed inside the constitutive update — most quantities work with $\mathbf{F}$ directly — but it IS needed for the spatial velocity gradient $\mathbf{L}$ and for stress push-forward. - - -**Algorithm: Nanson's Formula for Oriented-Area Pull-Back** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{n}_0\,\text{(reference normal)},\;dA_0\,\text{(reference area)},\;\mathbf{F},\;J$ -\State $\mathbf{N} \gets J\,\mathbf{F}^{-T}\cdot\mathbf{n}_0$ -\State $da \gets \|\mathbf{N}\|,\;\mathbf{n} \gets \mathbf{N}/da$ -\Return $\mathbf{n},\,da$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Boundary integrals over deformed surfaces use Nanson directly: traction $\mathbf{t}\,da = \boldsymbol{\sigma}\cdot\mathbf{n}\,da = \boldsymbol{\sigma}\cdot J\mathbf{F}^{-T}\mathbf{n}_0\,dA_0 = \mathbf{P}\cdot\mathbf{n}_0\,dA_0$, recovering the nominal stress. Run on every boundary Gauss point each step; cache $J\mathbf{F}^{-T}$ between volumetric and surface kernels. - - - -## 4. Known Pitfalls -**$J\to 0$ element inversion:** Element distortion drives $J\to 0$, which makes $\mathbf{F}^{-1}$ singular and corrupts every push-forward / pull-back / polar decomposition. Set $J_{\min}\sim 10^{-3}$, detect $J n+1)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{F}_{n+1},\,\mathbf{F}^p_n,\,q_n,\,\text{material law}$ -\State $\mathbf{F}^{e,\mathrm{trial}} \gets \mathbf{F}_{n+1}\,(\mathbf{F}^p_n)^{-1}$ -\State $\mathbf{C}^{e,\mathrm{trial}} \gets (\mathbf{F}^{e,\mathrm{trial}})^T\,\mathbf{F}^{e,\mathrm{trial}}$ -\State $\mathbf{S}^{e,\mathrm{trial}} \gets 2\,\partial \psi^e(\mathbf{C}^{e,\mathrm{trial}})/\partial \mathbf{C}^{e,\mathrm{trial}}$ -\State $\mathbf{M}^{\mathrm{trial}} \gets \mathbf{C}^{e,\mathrm{trial}}\,\mathbf{S}^{e,\mathrm{trial}}$ -\If{$f(\mathbf{M}^{\mathrm{trial}},q_n) \le 0$} -\State $\Delta\gamma \gets 0,\,\mathbf{F}^p_{n+1}\gets\mathbf{F}^p_n,\,q_{n+1}\gets q_n$ -\Else -\State $\text{solve for } \Delta\gamma \;\text{such that}\; f(\mathbf{M}_{n+1}(\Delta\gamma),\,q_{n+1}(\Delta\gamma)) = 0 \;\text{(local Newton)}$ -\State $\mathbf{N} \gets \partial f/\partial \mathbf{M}\,\big|_{\mathbf{M}_{n+1}}$ -\State $\mathbf{F}^p_{n+1} \gets \exp(\Delta\gamma\,\mathbf{N})\,\mathbf{F}^p_n$ -\State $\mathbf{F}^e_{n+1} \gets \mathbf{F}_{n+1}\,(\mathbf{F}^p_{n+1})^{-1}$ -\State $q_{n+1} \gets q_n + \Delta\gamma\,\hat q(\mathbf{M},q)$ -\EndIf -\State $\mathbf{S}^e_{n+1} \gets 2\partial \psi^e/\partial \mathbf{C}^e\,\big|_{\mathbf{C}^e_{n+1}},\,\mathbf{S}_{n+1} \gets (\mathbf{F}^p_{n+1})^{-1}\mathbf{S}^e_{n+1}(\mathbf{F}^p_{n+1})^{-T}$ -\Return $\mathbf{S}_{n+1},\,\mathbf{F}^p_{n+1},\,q_{n+1},\,\mathbb{C}_{ep}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Wrap the inner Newton iteration as a `@ti.func` that accepts the trial state and returns $\Delta\gamma$ and the converged $\mathbf{M}$. Use the closed-form 3x3 matrix exponential via spectral decomposition (`tensor-isotropic-functions`). Cache $(\mathbf{F}^p_n)^{-1}$ once at trial step, recompute $(\mathbf{F}^p_{n+1})^{-1}$ via cofactor only after convergence. The Lagrangian PK2 stress $\mathbf{S}_{n+1}$ is obtained from $\mathbf{S}^e_{n+1}$ via the inverse plastic pull-back; it is what enters the global FEM residual. - - -**Algorithm: Verify Plastic Incompressibility After Update** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{F}^p_{n+1},\,\text{tol}\;\tau$ -\State $d \gets \det\mathbf{F}^p_{n+1}$ -\If{$|d - 1| > \tau$} -\State $\mathbf{F}^p_{n+1} \gets d^{-1/3}\,\mathbf{F}^p_{n+1} \;\text{(volumetric correction)}$ -\EndIf -\Return $\mathbf{F}^p_{n+1}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Run as a sanity check after every plastic update for J2 / metal plasticity. Use $\tau=10^{-10}$ in double precision. The exponential-map update keeps $\det\mathbf{F}^p=1$ exactly in IEEE arithmetic IF $\mathrm{tr}\,\mathbf{N}=0$; the rare correction handles cases where the flow direction is not perfectly deviatoric (e.g., GTN with porosity $f\ne 0$). For pressure-sensitive plasticity (Drucker-Prager) skip this check entirely. - - - -## 4. Known Pitfalls -**Non-unique intermediate configuration:** $\mathbf{F}=\mathbf{F}^e\mathbf{F}^p$ is invariant under $(\mathbf{F}^e,\mathbf{F}^p)\to(\mathbf{F}^e\mathbf{H},\mathbf{H}^{-1}\mathbf{F}^p)$ for any $\mathbf{H}\in GL^+(3)$. Without an isoclinic / director-orientation convention the rotation between $\mathbf{F}^e$ and $\mathbf{F}^p$ is undetermined, and plastic spin $\mathbf{W}^p$ has no operational meaning. Either fix the intermediate configuration via material directors (lattice vectors in crystal plasticity, fiber tangents in composites) or specify a plastic-spin constitutive equation explicitly. - - -**Mixing additive and multiplicative splits:** $\mathbf{L}=\mathbf{L}^e+\mathbf{L}^p$ is WRONG in the multiplicative framework. The correct identity is $\mathbf{L}=\mathbf{L}^e+\mathbf{F}^e\mathbf{L}^p(\mathbf{F}^e)^{-1}$ — the plastic velocity gradient is pushed forward to the spatial frame by $\mathbf{F}^e$ before adding. The naive additive form is the most common bug in finite-strain plasticity codes; it surfaces under any non-trivial elastic stretch. - - -**Drift of plastic incompressibility under explicit integration:** Direct Euler updates $\mathbf{F}^p_{n+1}=\mathbf{F}^p_n+\Delta t\,\mathbf{L}^p\mathbf{F}^p_n$ do NOT preserve $\det\mathbf{F}^p=1$ even when $\mathrm{tr}\,\mathbf{D}^p=0$; the determinant drifts as $\mathcal{O}(\Delta t^2)$ per step and accumulates over thousands of steps into visible volumetric inflation / deflation. Use the exponential map $\mathbf{F}^p_{n+1}=\exp(\Delta\gamma\mathbf{N})\mathbf{F}^p_n$ which preserves the determinant exactly when $\mathrm{tr}\,\mathbf{N}=0$. - - -**Confusing Mandel stress with PK2 / Cauchy:** The flow rule in the multiplicative split is $\mathbf{L}^p=\dot\gamma\,\partial f/\partial\mathbf{M}$, NOT $\partial f/\partial\mathbf{S}$ or $\partial f/\partial\boldsymbol{\sigma}$. The Mandel stress $\mathbf{M}=\mathbf{C}^e\mathbf{S}^e$ is generally non-symmetric (unlike $\mathbf{S}$ and $\boldsymbol{\sigma}$), and substituting one for another breaks thermodynamic consistency of the plastic dissipation $\mathbf{M}\colon\mathbf{L}^p\ge 0$. For isotropic elasticity $\mathbf{M}$ becomes symmetric and the distinction collapses; for anisotropic elasticity it does NOT. - - -**Treating $\mathbf{F}^p$ as symmetric:** $\mathbf{F}^p$ is generally NOT symmetric — under simple shear with rotation $\mathbf{F}^p$ has both stretch and rotation components. Storing only the symmetric part (a common shortcut for "stretch only") drops the plastic spin and corrupts the intermediate configuration. Store $\mathbf{F}^p$ as a full $3\times 3$ matrix at every Gauss point. - - -**Polar decomposition applied to $\mathbf{F}$ instead of $\mathbf{F}^e$:** Corotational stress integration in finite-strain plasticity uses the polar decomposition of $\mathbf{F}^e$ (the elastic part), NOT of $\mathbf{F}$. Decomposing $\mathbf{F}=\mathbf{R}\mathbf{U}$ directly mixes elastic stretch with plastic flow direction and corrupts the algorithmic tangent. Always extract $\mathbf{F}^e=\mathbf{F}(\mathbf{F}^p)^{-1}$ first, then decompose. - - -**Sign / order errors in $\mathbf{S}=(\mathbf{F}^p)^{-1}\mathbf{S}^e(\mathbf{F}^p)^{-T}$:** The pull-back of $\mathbf{S}^e$ from $\bar\Omega$ to $\Omega_0$ is $\mathbf{S}=(\mathbf{F}^p)^{-1}\mathbf{S}^e(\mathbf{F}^p)^{-T}$ (kinetic, contravariant-contravariant tensor). Swapping $\mathbf{F}^p$ for $(\mathbf{F}^p)^{-1}$ or transposing the wrong leg silently corrupts the global PK2 stress that enters the FEM residual; the bug shows up as wrong reaction forces under finite plastic deformation. - - -**Forgetting the geometric correction in the consistent tangent:** The algorithmic tangent for the multiplicative split has multiple contributions: $\partial\mathbf{S}/\partial\mathbf{C}$ in the elastic block, $\partial\mathbf{F}^p/\partial\mathbf{F}$ from the plastic update, and the geometric correction from $\partial\mathbf{F}^e/\partial\mathbf{F}=\mathbf{I}\bar\otimes(\mathbf{F}^p)^{-T}-\mathbf{F}^e\partial\mathbf{F}^p/\partial\mathbf{F}\cdot(\mathbf{F}^p)^{-1}$. Dropping any term degrades Newton convergence from quadratic to linear and stalls solvers near limit points. - - -## 5. References -- Lee, E. H. (1969) — Elastic-plastic deformation at finite strains (origin of $\mathbf{F}=\mathbf{F}^e\mathbf{F}^p$ split) -- Mandel, J. (1972) — Plasticite classique et viscoplasticite (intermediate configuration, isoclinic axes, Mandel stress) -- Miehe, Apel, Lambrecht (2002) — Anisotropic additive plasticity in the logarithmic strain space (modular wrapper that bypasses explicit multiplicative split via log-strain) -- Holzapfel (2000) — Nonlinear Solid Mechanics (multiplicative split, plastic velocity gradient, exponential-map integration) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/kinematics-objective-rates.md b/packages/akms/src/akms/_bundled/global_nodes/kinematics-objective-rates.md deleted file mode 100644 index 2e2364d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/kinematics-objective-rates.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: kinematics-objective-rates -title: Objective Stress Rates -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- objectivity -- stress-rates -status: established -confidence: 0.9 -source: hybrid -edges: -- to: kinematics-velocity-gradient - type: requires - weight: 1.0 -- to: stress-cauchy-kirchhoff - type: requires - weight: 1.0 -- to: kinematics-lie-derivative - type: feeds-into - weight: 1.0 -- to: kinematics-corotational-update - type: feeds-into - weight: 1.0 -- to: stress-tangent-push-forward - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Objective Stress Rates - -## Summary - -Objective stress rates modify the material time derivative of Eulerian stress tensors to guarantee frame indifference under rigid-body rotations. Common formulations include the Jaumann rate, Green-Naghdi rate, Truesdell rate, and convected (Oldroyd) rates, which frame rate-type hypoelastic and elastoplastic constitutive laws in finite-deformation continuum mechanics. - -## 1. Core Concept - -In finite-strain continuum mechanics, rate-type constitutive laws relate stress rate measures to the rate of deformation tensor D. Simply taking the ordinary material time derivative of Cauchy stress \dot{\sigma} violates principle of material frame indifference because rigid-body rotations induce fictitious stress changes. Objective stress rates eliminate rotational contributions by subtracting spin-induced corotational terms or Lie derivative frame transformations. The Jaumann rate utilizes the continuum spin tensor W, but suffers from artificial stress oscillations in monotonic simple shear. The Green-Naghdi rate uses the rigid rotation tensor R from polar decomposition F = R U, eliminating shear oscillations. The Truesdell and Lie rates incorporate velocity gradient or metric transformation terms to maintain geometric invariance during finite stretching. - -## 2. Mathematical Formulation - -**Jaumann Objective Stress Rate** -$$ -\sigma^{\nabla J} = \dot{\sigma} - W \sigma + \sigma W -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 3.5, p. 137; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 11.2, p. 372; Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, Eq. A.2–A.3, pp. 47–48_ - -**Green-Naghdi Objective Stress Rate** -$$ -\sigma^{\nabla \mathrm{GN}} = \dot{\sigma} - \Omega_{\mathrm{GN}} \sigma + \sigma \Omega_{\mathrm{GN}}, \quad \Omega_{\mathrm{GN}} = \dot{R} R^T -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 3.5, p. 137; Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, Eq. A.3, p. 48; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 11.2, p. 372_ - -**Truesdell Objective Stress Rate** -$$ -\sigma^{\nabla T} = \dot{\sigma} - L \sigma - \sigma L^T + \sigma \mathrm{tr}(D) -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 3.5, p. 137; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.1, Eq. 12.19, p. 403_ - -**Convected (Oldroyd) Kirchhoff Stress Rate** -$$ -\tau^{\nabla c} = \dot{\tau}_{ij} g^i \otimes g^j -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, p. 779; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Sec. 4.3, p. 23_ - -**Notation:** -{'\\sigma': 'Cauchy stress tensor.', '\\dot{\\sigma}': 'Material time derivative of Cauchy stress tensor.', '\\sigma^{\\nabla J}': 'Jaumann objective rate of Cauchy stress.', '\\sigma^{\\nabla \\mathrm{GN}}': 'Green-Naghdi objective rate of Cauchy stress.', '\\sigma^{\\nabla T}': 'Truesdell objective rate of Cauchy stress.', 'L': 'Spatial velocity gradient tensor L = \\nabla v.', 'W': 'Spin tensor W = \\mathrm{skw}(L).', 'D': 'Rate of deformation tensor D = \\mathrm{sym}(L).', 'R': 'Proper orthogonal rotation tensor from polar decomposition F = R U.'} - - -## 3. Algorithmic Implementation - -**Explicit Hypoelastic Objective Stress Rate Integration Step** -$$ -\begin{algorithmic} -\State $Given current spatial velocity gradient L = \nabla v and Cauchy stress \sigma_n$ -\State $Extract rate of deformation D \gets \frac{1}{2}(L + L^T) \text{ and spin tensor } W \gets \frac{1}{2}(L - L^T)$ -\If{$Objective rate is Jaumann rate$} -\State $Compute spin tensor \Omega \gets W$ -\Else -\EndIf -\State $Evaluate elastic stress rate \dot{\sigma}^{\circ} \gets C^{\mathrm{e}} : D$ -\State $Compute Cauchy stress time derivative \dot{\sigma} \gets \dot{\sigma}^{\circ} + \Omega \sigma_n - \sigma_n \Omega$ -\State $Update Cauchy stress \sigma_{n+1} \gets \sigma_n + \Delta t \, \dot{\sigma}$ -\Return $\sigma_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 12.1, p. 415; Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, p. 47_ - - -## 4. Known Pitfalls - -- **Spurious Stress Oscillations in Monotonic Simple Shear under Jaumann Rate**: Integrating hypoelastic constitutive models using the Jaumann stress rate during large monotonic simple shear produces non-physical sinusoidal oscillations in shear and normal stresses. Mitigation: Substitute the Green-Naghdi stress rate based on polar rotation R or adopt hyperelastic-plastic multiplicative stress formulations. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 11.2, p. 372 & Sec. 12.4, Fig. 12.2, p. 414; Rashid - 1993 - Incremental kinematics for finite element applications.pdf, Sec. 2, p. 3941)_ -- **Loss of Frame Indifference from Material Time Derivatives**: Directly integrating the material time derivative of Cauchy stress \dot{\sigma} in finite deformation analysis violates material frame indifference (objectivity), generating unphysical stresses during rigid-body rotation. Mitigation: Express rate constitutive equations using objective stress rates (such as Jaumann, Green-Naghdi, or Truesdell rates) or corotational frame updates. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 3.5, p. 137; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Sec. 4.1–4.3, pp. 21–23)_ - -## References - -- Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Rashid - 1993 - Incremental kinematics for finite element applications.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/kinematics-polar-decomposition.md b/packages/akms/src/akms/_bundled/global_nodes/kinematics-polar-decomposition.md deleted file mode 100644 index a30482d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/kinematics-polar-decomposition.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -id: kinematics-polar-decomposition -title: Polar Decomposition & Rotation Tensor -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- polar-decomposition -- rotation -status: established -confidence: 0.9 -source: hybrid -edges: -- to: kinematics-motion-deformation-gradient - type: requires - weight: 1.0 -- to: tensor-spectral-decomposition - type: requires - weight: 1.0 -- to: kinematics-strain-tensors - type: feeds-into - weight: 1.0 -- to: kinematics-logarithmic-strain - type: feeds-into - weight: 1.0 -- to: kinematics-corotational-update - type: feeds-into - weight: 0.9 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Polar Decomposition & Rotation Tensor - -## Summary - -The polar decomposition theorem multiplicatively decomposes the deformation gradient tensor F into a proper orthogonal rotation tensor R and a symmetric positive-definite stretch tensor—either the right stretch tensor U or the left stretch tensor V. This decomposition isolates rigid-body rotation from pure material stretching, forming the foundation for objective stress rates, logarithmic strain evaluations, and corotational continuum formulations. - -## 1. Core Concept - -In finite deformation kinematics, any non-singular deformation gradient F with positive determinant (J = det F > 0) can be uniquely factored into F = R U (right polar decomposition) or F = V R (left polar decomposition). The tensor R is proper orthogonal (R^T R = I, det R = +1) and represents local rigid-body rotation. The right stretch tensor U operates in the reference material configuration, whereas the left stretch tensor V operates in the current spatial configuration, related by V = R U R^T. Stretches are evaluated via the square roots of the Cauchy-Green deformation tensors C = F^T F = U^2 and b = F F^T = V^2, typically computed using spectral decomposition of C or explicit closed-form matrix square root algorithms. - -## 2. Mathematical Formulation - -**Right and Left Polar Decomposition** -$$ -F = R U = V R, \quad R^T R = I, \quad \det R = +1 -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 3.7.1, Eqs. 3.7.1–3.7.2, p. 131; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, Eqs. 3.58 & 3.62, pp. 86–87_ - -**Stretch Tensor and Cauchy-Green Relations** -$$ -C = F^T F = U^2, \quad b = F F^T = V^2, \quad V = R U R^T -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, Eqs. 3.59–3.63, pp. 86–87; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Sec. 6.1, p. 28_ - -**Spectral Representation of Stretch and Rotation** -$$ -U = \sum_{i=1}^3 \lambda_i \boldsymbol{N}_i \otimes \boldsymbol{N}_i, \quad V = \sum_{i=1}^3 \lambda_i \boldsymbol{n}_i \otimes \boldsymbol{n}_i, \quad R = \sum_{i=1}^3 \boldsymbol{n}_i \otimes \boldsymbol{N}_i -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, pp. 85–86 & Box 11.3, p. 387; Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Sec. 2.10.5, Eqs. 2.10.70–2.10.71, p. 2_ - -**Explicit Incremental Rotation Extraction Formula** -$$ -R = F U^{-1} = F (F^T F)^{-1/2} -$$ -_Source: Rashid - 1993 - Incremental kinematics for finite element applications.pdf, Sec. 2 & 3, pp. 3940–3941; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, p. 86_ - -**Notation:** -{'F': 'Deformation gradient tensor F = \\partial \\boldsymbol{x} / \\partial \\boldsymbol{X}.', 'R': 'Proper orthogonal rotation tensor.', 'U': 'Symmetric positive-definite right stretch tensor.', 'V': 'Symmetric positive-definite left stretch tensor.', 'C': 'Right Cauchy-Green deformation tensor C = F^T F.', 'b': 'Left Cauchy-Green deformation tensor b = F F^T.', '\\lambda_i': 'Principal stretch ratios (\\lambda_i > 0).', '\\boldsymbol{N}_i, \\boldsymbol{n}_i': 'Orthonormal principal material and spatial direction vectors.'} - - -## 3. Algorithmic Implementation - -**Polar Decomposition via Spectral Decomposition of C** -$$ -\begin{algorithmic} -\State $Given 3x3 deformation gradient tensor F with \det F > 0$ -\State $Compute right Cauchy-Green deformation tensor C \gets F^T F$ -\State $Solve spectral eigenvalue problem for C to obtain eigenvalues \lambda_i^2 and orthonormal eigenvectors \boldsymbol{N}_i for i \in \{1, 2, 3\}$ -\For{$i \gets 1 \text{ to } 3$} -\State $Compute principal stretches \lambda_i \gets \sqrt{\lambda_i^2}$ -\State $Form material eigenprojection tensor E_i \gets \boldsymbol{N}_i \otimes \boldsymbol{N}_i$ -\EndFor -\State $Construct right stretch tensor U \gets \sum_{i=1}^3 \lambda_i E_i$ -\State $Compute inverse right stretch tensor U^{-1} \gets \sum_{i=1}^3 \left(\frac{1}{\lambda_i}\right) E_i$ -\State $Compute proper orthogonal rotation tensor R \gets F U^{-1}$ -\State $Compute left stretch tensor V \gets R U R^T$ -\Return $R, U, V$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, pp. 85–86 & Box 11.3, p. 387; Rashid - 1993 - Incremental kinematics for finite element applications.pdf, Sec. 2 & 3, pp. 3940–3941_ - - -## 4. Known Pitfalls - -- **Inverting Ill-Conditioned Stretch Tensors Near Zero Stretches**: Evaluating R = F U^{-1} when elements undergo extreme localized distortion or near-zero stretches (\lambda_i \to 0) causes U to become nearly singular, leading to severe numerical ill-conditioning and loss of orthogonality in R. Mitigation: Use robust spectral decomposition or closed-form Cayley-Hamilton square-root algorithms that precondition or clamp small principal stretches. _(Source: Rashid - 1993 - Incremental kinematics for finite element applications.pdf, Sec. 3, pp. 3943–3945; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.3, p. 387)_ -- **Coaxiality Misconception Between Stress and Deformation Gradients**: Assuming that principal stress directions always align with principal directions of the deformation gradient F or stretch tensor U. Coaxiality only holds for isotropic materials where principal axes of Cauchy stress \sigma coincide with left stretch tensor V, whereas anisotropic materials introduce distinct preferred material axes. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, p. 86 & Sec. 11.8, p. 386; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Sec. 2, pp. 5385–5387)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf -- Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf -- Rashid - 1993 - Incremental kinematics for finite element applications.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/kinematics-strain-tensors.md b/packages/akms/src/akms/_bundled/global_nodes/kinematics-strain-tensors.md deleted file mode 100644 index fe9ea44..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/kinematics-strain-tensors.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: kinematics-strain-tensors -title: Strain Tensors & Seth-Hill Family -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- strain-tensor -- seth-hill -status: established -confidence: 0.9 -source: hybrid -edges: -- to: kinematics-motion-deformation-gradient - type: requires - weight: 1.0 -- to: kinematics-polar-decomposition - type: requires - weight: 0.9 -- to: tensor-spectral-decomposition - type: requires - weight: 0.8 -- to: kinematics-logarithmic-strain - type: feeds-into - weight: 1.0 -- to: stress-piola-kirchhoff - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Strain Tensors & Seth-Hill Family - -## Summary - -Strain tensors measure continuous body deformation by quantifying local changes in length, angle, and volume relative to reference or spatial configurations. Finite strain measures include the Green-Lagrange material strain tensor, spatial Euler-Almansi strain, logarithmic (Hencky) strain, and generalized Seth-Hill family strains. - -## 1. Core Concept - -In finite-deformation continuum mechanics, displacement gradients contain both rigid-body motion and true stretching. Strain tensors eliminate rigid-body rotations by measuring metric variations between configurations. The Green-Lagrange strain tensor E evaluates changes in the squared lengths of material line elements in reference coordinates and is energetically conjugate to Second Piola-Kirchhoff stress. The spatial Euler-Almansi strain tensor e measures deformation in the current configuration and is related to E via geometric pull-back operations. The class of Seth-Hill strain measures generalizes finite strain metrics, incorporating logarithmic (Hencky) strain E = 1/2 ln C, which decouples volumetric and isochoric responses and facilitates additive elastoplastic splits. - -## 2. Mathematical Formulation - -**Green-Lagrange Material Strain Tensor** -$$ -E = \frac{1}{2}(C - I) = \frac{1}{2}(F^T F - I) -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, Eq. 3.61, p. 88; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 3.2.6, Eq. 3.2.20, p. 83_ - -**Green-Lagrange Strain Component Expression** -$$ -E_{IJ} = \frac{1}{2}\left( \frac{\partial x_k}{\partial X_I} \frac{\partial x_k}{\partial X_J} - \delta_{IJ} \right) = \frac{1}{2}\left( \frac{\partial u_I}{\partial X_J} + \frac{\partial u_J}{\partial X_I} + \frac{\partial u_k}{\partial X_I} \frac{\partial u_k}{\partial X_J} \right) -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, Eq. 3.61, p. 88; Bathe et al_1975_Finite element formulations for large deformation dynamic analysis.pdf, App. Nomenclature, p. 384_ - -**Logarithmic (Hencky) Strain Tensor** -$$ -E = \frac{1}{2} \ln C = \ln U = \sum_{i=1}^3 (\ln \lambda_i) \boldsymbol{N}_i \otimes \boldsymbol{N}_i -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 11.8, Eq. 11.108, p. 388; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Sec. 2.3 & Box 2, pp. 5385, 5390_ - -**Spatial Euler-Almansi and Pull-Back Relation** -$$ -E = \phi^* e = \frac{1}{2}(\phi^* g - G) -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.3, p. 34; Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf, Sec. 2.12, pp. 1–2_ - -**Notation:** -{'F': 'Deformation gradient tensor F = \\partial x / \\partial X.', 'C': 'Right Cauchy-Green deformation tensor C = F^T F.', 'E': 'Green-Lagrange material strain tensor.', 'e': 'Euler-Almansi spatial strain tensor.', 'U': 'Right pure stretch tensor U = C^{1/2}.', '\\lambda_i': 'Principal stretch ratios.', '\\boldsymbol{N}_i': 'Material principal directions (eigenvectors of C).', '\\phi^*': 'Pull-back geometric mapping operator.'} - - -## 3. Algorithmic Implementation - -**Material Green-Lagrange and Logarithmic Strain Evaluation Algorithm** -$$ -\begin{algorithmic} -\State $Given 3x3 deformation gradient tensor F$ -\State $Compute right Cauchy-Green tensor C \gets F^T F$ -\State $Compute Green-Lagrange strain tensor E^{\mathrm{GL}} \gets \frac{1}{2}(C - I)$ -\State $Solve spectral eigenvalues \lambda_i^2 and eigenvectors \boldsymbol{N}_i of C for i \in \{1, 2, 3\}$ -\For{$i \gets 1 \text{ to } 3$} -\State $Compute principal stretches \lambda_i \gets \sqrt{\lambda_i^2} \text{ and eigenprojections } E_i \gets \boldsymbol{N}_i \otimes \boldsymbol{N}_i$ -\EndFor -\State $Compute logarithmic strain tensor E^{\mathrm{log}} \gets \sum_{i=1}^3 (\ln \lambda_i) E_i$ -\Return $E^{\mathrm{GL}}, E^{\mathrm{log}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, p. 88 & Sec. 11.8, p. 388; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Box 2 & Box 3, pp. 5390, 5393_ - - -## 4. Known Pitfalls - -- **Using Small-Strain Tensor Linearizations in Large Deformation Kinematics**: Omitting non-linear displacement gradient terms \frac{1}{2} \frac{\partial u_k}{\partial X_I} \frac{\partial u_k}{\partial X_J} when evaluating strains under finite rotations induces severe artificial volume changes and invalidates energy conjugacy with Second Piola-Kirchhoff stresses. Mitigation: Compute full Green-Lagrange strain E = \frac{1}{2}(F^T F - I) or corotational strain updates. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.3, pp. 88–91; Bathe et al_1975_Finite element formulations for large deformation dynamic analysis.pdf, App. Nomenclature, p. 384)_ -- **Additive Stacking of Non-Coaxial Large Strain Tensors**: Additively accumulating finite strain increments without mapping to a common reference configuration or logarithmic strain space violates kinematic exactness when principal axes rotate. Mitigation: Transform strain tensors via push-forward/pull-back operators or evaluate strains in logarithmic strain space. _(Source: Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Sec. 2.1–2.3, pp. 5384–5385; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.3, p. 34)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Bathe et al_1975_Finite element formulations for large deformation dynamic analysis.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf -- Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/kinematics-velocity-gradient.md b/packages/akms/src/akms/_bundled/global_nodes/kinematics-velocity-gradient.md deleted file mode 100644 index 50844c3..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/kinematics-velocity-gradient.md +++ /dev/null @@ -1,224 +0,0 @@ ---- -id: kinematics-velocity-gradient -title: Velocity Gradient, Stretching & Spin -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- velocity-gradient -- rate-of-deformation -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: kinematics-motion-deformation-gradient - type: requires - weight: 1.0 - note: $\mathbf{L}=\dot{\mathbf{F}}\mathbf{F}^{-1}$ uses $\mathbf{F}$ from the deformation gradient -- to: tensor-products-contractions - type: requires - weight: 0.7 - note: Decomposition $\mathbf{L}=\mathbf{D}+\mathbf{W}$ uses sym/skew operators -- to: kinematics-strain-tensors - type: feeds-into - weight: 1.0 - note: Pull-back $\dot{\mathbf{E}}=\mathbf{F}^T\mathbf{D}\mathbf{F}$ ties rate-of-deformation to Green strain rate -- to: kinematics-objective-rates - type: feeds-into - weight: 1.0 - note: Spin $\mathbf{W}$ and rate-of-deformation $\mathbf{D}$ enter Jaumann / Truesdell / Green-Naghdi rates -context_size: medium -reading_priority: full -load_with: -- kinematics-motion-deformation-gradient -content_ref: null -akms_schema: v2 ---- - -# Velocity Gradient, Stretching & Spin - -## Summary -The spatial velocity gradient $\mathbf{L}=\nabla\mathbf{v}=\dot{\mathbf{F}}\mathbf{F}^{-1}$ (mixed-variance, generally asymmetric) decomposes additively into the symmetric rate-of-deformation $\mathbf{D}=\tfrac12(\mathbf{L}+\mathbf{L}^T)$ and the skew spin $\mathbf{W}=\tfrac12(\mathbf{L}-\mathbf{L}^T)$. $\mathbf{D}$ measures the rate of stretching and shearing (the kinematic strain rate), $\mathbf{W}$ measures the local rate of rigid rotation. Pull-back / push-forward links $\mathbf{D}$ to the Green strain rate via $\dot{\mathbf{E}}=\mathbf{F}^T\mathbf{D}\mathbf{F}$. Power-conjugacy gives a hierarchy of equivalent internal-power expressions: $\boldsymbol{\sigma}\colon\mathbf{D}\,dv = \boldsymbol{\tau}\colon\mathbf{D}\,(dv/J) = \mathbf{S}\colon\dot{\mathbf{E}}\,dV_0 = \mathbf{P}\colon\dot{\mathbf{F}}\,dV_0$. In FEM $\mathbf{L}$ is built per Gauss point from nodal velocities and shape function spatial gradients; the asymmetry of $\mathbf{L}$ matters and must not be discarded by Voigt storage. - - -## 1. Core Concept -The velocity gradient $\mathbf{L}$ is the rate analogue of the deformation gradient: $\dot{\mathbf{F}}=\mathbf{L}\mathbf{F}$ shows that $\mathbf{L}$ generates the time evolution of $\mathbf{F}$. Its symmetric part $\mathbf{D}$ is the local rate of stretching of material line elements (the "strain rate" as measured in the current configuration), while its skew part $\mathbf{W}$ is the angular velocity of the principal axes — the rate at which the material rotates about itself. The decomposition $\mathbf{L}=\mathbf{D}+\mathbf{W}$ is the kinematic backbone of every rate-form constitutive law. Power conjugacy ties $\mathbf{D}$ to the Cauchy / Kirchhoff stress: $\boldsymbol{\sigma}\colon\mathbf{D}$ is the Eulerian internal-power density per current volume, and pull-back to the reference configuration recovers the Lagrangian $\mathbf{S}\colon\dot{\mathbf{E}}$. Hyperelastic, plastic, and viscous constitutive laws are written in terms of $\mathbf{D}$ (or its non-coaxial corrections via objective rates), so getting $\mathbf{D}$ and $\mathbf{W}$ right at every Gauss point is essential. - - -## 2. Mathematical Formulation -Throughout, $\mathbf{v}=\partial\boldsymbol{\phi}/\partial t|_{\mathbf{X}}$ is the material velocity (function of $\mathbf{X}$), $\dot{\mathbf{F}}$ is the material time derivative of the deformation gradient. Spatial gradient $\nabla=\partial/\partial\mathbf{x}$, material gradient $\nabla_0=\partial/\partial\mathbf{X}$. - - -**Spatial velocity gradient:** - -$$ -\mathbf{L} = \nabla\mathbf{v} = \frac{\partial \mathbf{v}}{\partial \mathbf{x}} = \dot{\mathbf{F}}\,\mathbf{F}^{-1},\qquad -L_{ij} = \frac{\partial v_i}{\partial x_j} -$$ - -where Mixed-variance two-leg tensor (one contravariant, one covariant); generally asymmetric - -**Sym / skew decomposition:** - -$$ -\mathbf{L} = \mathbf{D} + \mathbf{W},\qquad -\mathbf{D} = \tfrac{1}{2}(\mathbf{L}+\mathbf{L}^T),\qquad -\mathbf{W} = \tfrac{1}{2}(\mathbf{L}-\mathbf{L}^T) -$$ - -where $\mathbf{D}=\mathbf{D}^T$ rate-of-deformation; $\mathbf{W}=-\mathbf{W}^T$ spin - -**Time rate of $\mathbf{F}$:** - -$$ -\dot{\mathbf{F}} = \mathbf{L}\,\mathbf{F},\qquad -\dot{F}_{iJ} = L_{ik}\,F_{kJ} -$$ - -where $\mathbf{L}$ is the spatial generator of $\dot{\mathbf{F}}$ - -**Pull-back of $\mathbf{D}$ to Green strain rate:** - -$$ -\dot{\mathbf{E}} = \mathbf{F}^T\,\mathbf{D}\,\mathbf{F},\qquad -\mathbf{D} = \mathbf{F}^{-T}\,\dot{\mathbf{E}}\,\mathbf{F}^{-1} -$$ - -where Kinematic (covariant-covariant) push-forward / pull-back; verifies $\mathbf{S}\colon\dot{\mathbf{E}}=\boldsymbol{\tau}\colon\mathbf{D}$ - -**Internal power conjugacy:** - -$$ -\int_{\Omega_t}\boldsymbol{\sigma}\colon\mathbf{D}\,dv -= \int_{\Omega_t}\boldsymbol{\tau}\colon\mathbf{D}\,\frac{dv}{J} -= \int_{\Omega_0}\mathbf{S}\colon\dot{\mathbf{E}}\,dV_0 -= \int_{\Omega_0}\mathbf{P}\colon\dot{\mathbf{F}}\,dV_0 -$$ - -where Same internal power expressed in four equivalent stress / strain-rate pairings - -**Spin axis vector:** - -$$ -\mathbf{W} = \begin{pmatrix} 0 & -\omega_3 & \omega_2 \\ \omega_3 & 0 & -\omega_1 \\ -\omega_2 & \omega_1 & 0 \end{pmatrix}, -\qquad -\boldsymbol{\omega} = -\tfrac{1}{2}\,e_{ijk}\,W_{jk}\,\mathbf{e}_i -$$ - -where $\boldsymbol{\omega}$ is the local angular velocity vector of the material - -**Vorticity:** - -$$ -\boldsymbol{\zeta} = \nabla\times\mathbf{v} = 2\,\boldsymbol{\omega} -$$ - -where Curl of velocity is twice the spin axis - -**Plastic velocity gradient (multiplicative split):** - -$$ -\mathbf{L}^p = \dot{\mathbf{F}}^p\,(\mathbf{F}^p)^{-1},\qquad -\mathbf{L} = \mathbf{L}^e + \mathbf{F}^e\,\mathbf{L}^p\,(\mathbf{F}^e)^{-1} -$$ - -where Used in finite-strain plasticity; mixed variance carries through to $\mathbf{L}^p$ (`kinematics-multiplicative-decomp`) - -**Notation:** - -- $\mathbf{v}$ — Spatial velocity field -- $\mathbf{L}$ — Spatial velocity gradient, $\mathbf{L}=\nabla\mathbf{v}=\dot{\mathbf{F}}\mathbf{F}^{-1}$ -- $\mathbf{D}$ — Rate-of-deformation, $\mathbf{D}=\tfrac12(\mathbf{L}+\mathbf{L}^T)$ (symmetric) -- $\mathbf{W}$ — Spin tensor, $\mathbf{W}=\tfrac12(\mathbf{L}-\mathbf{L}^T)$ (skew) -- $\boldsymbol{\omega}$ — Angular velocity vector dual to $\mathbf{W}$ -- $\boldsymbol{\zeta}$ — Vorticity, $\boldsymbol{\zeta}=\nabla\times\mathbf{v}=2\boldsymbol{\omega}$ -- $\dot{\mathbf{E}}$ — Material time derivative of Green-Lagrange strain -- $\mathbf{F}^e,\mathbf{F}^p$ — Elastic / plastic parts of the multiplicative split - - -## 3. Algorithmic Implementation -**Algorithm: Compute $\mathbf{L},\mathbf{D},\mathbf{W}$ at a Gauss Point** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \{\mathbf{v}_a\}_{a=1}^{n_n},\,\{\partial N_a/\partial \mathbf{x}\}_{a=1}^{n_n} \;\text{at the GP},\,\mathbf{F}$ -\State $\mathbf{L} \gets \mathbf{0} \in \mathbb{R}^{3\times 3}$ -\For{$a = 1,\ldots,n_n$} -\For{$i,j = 1,2,3$} -\State $L_{ij} \mathrel{+}= v_{a,i}\,(\partial N_a/\partial x_j)$ -\EndFor -\EndFor -\For{$i,j = 1,2,3$} -\State $D_{ij} \gets \tfrac{1}{2}(L_{ij} + L_{ji})$ -\State $W_{ij} \gets \tfrac{1}{2}(L_{ij} - L_{ji})$ -\EndFor -\Return $\mathbf{L},\mathbf{D},\mathbf{W}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -`@ti.func` per Gauss point. The spatial shape function gradients $\partial N_a/\partial\mathbf{x}=\partial N_a/\partial\mathbf{X}\cdot\mathbf{F}^{-1}$ change every step in TL-FEM; in UL-FEM they are computed from current geometry directly. Store $\mathbf{D}$ as a full $3\times 3$ symmetric matrix or a 6-component Mandel vector — never as a Voigt vector that would lose factor-of-2 bookkeeping in shear blocks. - - -**Algorithm: Pull-Back $\mathbf{D}\to\dot{\mathbf{E}}$ and Verify Conjugacy** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{D},\,\mathbf{F},\,\mathbf{S},\,\boldsymbol{\sigma}$ -\State $\dot{\mathbf{E}} \gets \mathbf{F}^T\,\mathbf{D}\,\mathbf{F}$ -\State $P^{\mathrm{mat}}_{\mathrm{int}} \gets \mathbf{S}\colon\dot{\mathbf{E}} \;\text{(Lagrangian)}$ -\State $P^{\mathrm{spt}}_{\mathrm{int}} \gets \boldsymbol{\sigma}\colon\mathbf{D} \;\text{(Eulerian)}$ -\State $P^{\mathrm{spt}}_{\mathrm{int}} \cdot J = \mathbf{S}\colon\dot{\mathbf{E}} \;\text{(must hold to round-off)}$ -\Return $\dot{\mathbf{E}}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Use as a unit test in development; the equality $\boldsymbol{\sigma}\colon\mathbf{D}\,J = \mathbf{S}\colon\dot{\mathbf{E}}$ is a rigorous check on internal-power consistency. Failures usually indicate Voigt factor-of-2 errors in shear or wrong stress / strain-rate pairing in the constitutive update. - - -**Algorithm: Update $\mathbf{F}$ via Exponential Map (Structure-Preserving)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{F}_n,\,\mathbf{L}_{n+1/2},\,\Delta t$ -\State $\mathbf{F}_{n+1} \gets \exp(\Delta t\,\mathbf{L}_{n+1/2})\,\mathbf{F}_n$ -\Return $\mathbf{F}_{n+1}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Closed-form $3\times 3$ matrix exponential via spectral decomposition (`tensor-isotropic-functions`). Preserves $\det\mathbf{F}$ exactly when $\mathrm{tr}(\Delta t\,\mathbf{L})=0$ (incompressible flow) and preserves $\mathbf{F}\in GL^+(3)$ unconditionally. Substantially more stable than the direct update $\mathbf{F}_{n+1}=\mathbf{F}_n+\Delta t\,\mathbf{L}\mathbf{F}_n$ for large $\Delta t$ at a moderate cost penalty. - - - -## 4. Known Pitfalls -**$\mathbf{L}$ is asymmetric — separate $\mathbf{D}$ and $\mathbf{W}$ consistently:** Storing $\mathbf{L}$ in a 6-component symmetric form loses the spin part and corrupts every objective stress integration that depends on $\mathbf{W}$. Always store $\mathbf{L}$ as a full $3\times 3$ matrix (9 components) or store $\mathbf{D}$ (6) and $\mathbf{W}$ (3) separately. The vector form of $\mathbf{W}$ is $\boldsymbol{\omega}=-\tfrac12 e_{ijk}W_{jk}\mathbf{e}_i$, which compresses to 3 numbers without loss. - - -**Time-step instability from finite-difference $\dot{\mathbf{F}}$:** Computing $\mathbf{L}=\dot{\mathbf{F}}\mathbf{F}^{-1}$ via $\dot{\mathbf{F}}\approx(\mathbf{F}_{n+1}-\mathbf{F}_n)/\Delta t$ amplifies time-step noise and produces oscillatory $\mathbf{D}$ that drives spurious plastic flow. Build $\mathbf{L}$ from the spatial velocity gradient $\nabla\mathbf{v}$ directly (using nodal velocities and shape function gradients), not from finite differences on $\mathbf{F}$. - - -**Treating $\dot{\mathbf{E}}$ as identical to $\mathbf{D}$:** $\mathbf{D}=\mathbf{F}^{-T}\dot{\mathbf{E}}\mathbf{F}^{-1}$ — they coincide only when $\mathbf{F}=\mathbf{I}$ (small strain) or for purely coaxial flow. Using $\mathbf{D}$ in place of $\dot{\mathbf{E}}$ in a Lagrangian constitutive update introduces a spurious push-forward that breaks the $\mathbf{S}\leftrightarrow\dot{\mathbf{E}}$ conjugacy and corrupts the consistent tangent. - - -**Voigt factor-of-2 confusion on shear strain rate:** In the kinematic Voigt form $\{\mathbf{D}\}=(D_{11},D_{22},D_{33},2D_{23},2D_{13},2D_{12})^T$ — shear components carry the factor 2. Forgetting it produces shear stress that is half of correct, breaks $\boldsymbol{\sigma}\colon\mathbf{D}=\{\boldsymbol{\sigma}\}^T\{\mathbf{D}\}$, and shows up only on shear-dominated benchmarks (uniaxial tests are insensitive). - - -**$\mathbf{W}$ not trace-free in 2D / plane-strain:** $\mathbf{W}$ is mathematically skew-symmetric and exactly trace-free, but careless plane-strain projections that zero-pad the out-of-plane components can produce $W_{33}\ne 0$ from round-off in the symmetric-skew split. Validate $|\mathrm{tr}\,\mathbf{W}|<10^{-12}\|\mathbf{L}\|$ at every Gauss point; fix the projection at construction rather than masking by truncation later. - - -**Mixing material and spatial gradients in $\mathbf{L}$:** $\mathbf{L}$ is a SPATIAL gradient: $\partial\mathbf{v}/\partial\mathbf{x}$. Computing it as the material gradient $\partial\mathbf{v}/\partial\mathbf{X}$ (a common slip in TL-FEM where shape function gradients are stored in reference form) gives $\dot{\mathbf{F}}$ instead, which has different mixed-variance structure and yields wrong $\mathbf{D}$ and $\mathbf{W}$. Convert via $\partial\mathbf{v}/\partial\mathbf{x}=(\partial\mathbf{v}/\partial\mathbf{X})\cdot\mathbf{F}^{-1}$. - - -**Multiplicative split: $\mathbf{L}\ne\mathbf{L}^e+\mathbf{L}^p$ without push-forward:** The multiplicative split $\mathbf{F}=\mathbf{F}^e\mathbf{F}^p$ does NOT translate to $\mathbf{L}=\mathbf{L}^e+\mathbf{L}^p$. The correct identity is $\mathbf{L}=\mathbf{L}^e+\mathbf{F}^e\mathbf{L}^p(\mathbf{F}^e)^{-1}$ (the plastic part is pushed forward to the current configuration). Treating it as additive in $\mathbf{L}$ — a common error in elastoplastic codes — corrupts the plastic flow direction and breaks objectivity. - - -## 5. References -- Belytschko, Liu, Moran & Elkhodary (2014) — Nonlinear Finite Elements for Continua and Structures, 2nd ed. (velocity gradient, sym/skew decomposition, conjugacy table, pull-back of $\mathbf{D}$) -- Holzapfel (2000) — Nonlinear Solid Mechanics (rate-of-deformation, spin, vorticity, exponential map for $\mathbf{F}$) -- de Borst, Crisfield, Remmers & Verhoosel (2012) — Nonlinear Finite Element Analysis of Solids and Structures, 2nd ed. (velocity gradient in updated Lagrangian formulations) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/knowledge/graph/graph.json b/packages/akms/src/akms/_bundled/global_nodes/knowledge/graph/graph.json deleted file mode 100644 index 4b5e630..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/knowledge/graph/graph.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "directed": true, - "graph": { - "akms_schema": "v2", - "edge_count": 0, - "generated_at": "2026-08-31T10:43:51", - "global_vault": "~/.claude/akms/nodes", - "node_count": 0, - "repo_id": "global_nodes" - }, - "links": [], - "multigraph": false, - "nodes": [] -} \ No newline at end of file diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-action-auto-creation.md b/packages/akms/src/akms/_bundled/global_nodes/moose-action-auto-creation.md deleted file mode 100644 index 8b3d896..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-action-auto-creation.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -id: moose-action-auto-creation -title: MOOSE MOOSE Action system and automatic object creation -domain: architecture -subdomain: procedural -tags: -- action -- tensor-mechanics-action -- action-warehouse -- syntax-association -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-action-system - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-action-system ---- - -# MOOSE MOOSE Action system and automatic object creation - -MOOSE's Action system is a core component that translates high-level input file blocks into the low-level objects required for a simulation . This system uses `Action` classes to orchestrate the creation and configuration of various MOOSE objects like `Kernels`, `Variables`, and `Materials` based on user input . The `ActionWarehouse` manages the ordering and execution of these `Action`s, ensuring proper setup of the simulation . - -## 1. What is an `Action`? How does it differ from the objects it creates? - -An `Action` is a C++ class that performs setup tasks, often involving the creation of MOOSE objects . It differs from the objects it creates in that an `Action` is a temporary construct used during the input file parsing and setup phase, whereas the objects it creates (e.g., `Kernels`, `Variables`, `Materials`) are the actual components that constitute the simulation problem and persist throughout the simulation's lifetime . - -The base class for all actions is `Action` . A specialized type, `MooseObjectAction`, is used when the action's primary purpose is to create other MOOSE objects from an input file . The `act()` method is the core of an `Action`, where the logic for creating objects or performing other setup tasks is implemented . - -## 2. `TensorMechanics/Master` action (now `Physics/SolidMechanics/QuasiStatic`): what objects does it auto-generate? - -The `Physics/SolidMechanics/QuasiStatic` action (formerly `TensorMechanics/Master`) is a high-level action that auto-generates a suite of low-level MOOSE objects to set up a quasi-static solid mechanics problem . - -This action can generate: -* **Stress Divergence Kernels**: For calculating stress divergence equilibrium, with options for `StressDivergenceTensors`, `WeakPlaneStress`, `StressDivergenceRZTensors`, or `StressDivergenceRSphericalTensors` in the old kernel system . For the new Lagrangian kernel system, it generates `TotalLagrangianStressDivergence` or `UpdatedLagrangianStressDivergence` . -* **Displacement Variables**: Adds `Variables` for displacement fields . -* **Strain Calculators**: Depending on the `strain` parameter, it can add `ComputeFiniteStrain`, `ComputePlaneFiniteStrain`, `ComputeAxisymmetric1DFiniteStrain`, `ComputeAxisymmetricRZFiniteStrain`, `ComputeSmallStrain`, `ComputePlaneSmallStrain`, `ComputeAxisymmetric1DSmallStrain`, `ComputeAxisymmetricRZSmallStrain`, `ComputeIncrementalStrain`, `ComputePlaneIncrementalStrain`, `ComputeAxisymmetric1DIncrementalStrain`, or `ComputeAxisymmetricRZIncrementalStrain` . For the new Lagrangian system, it uses `ComputeLagrangianStrain` . -* **AuxVariables and AuxKernels**: For outputting various tensor components and quantities, such as `RankTwoAux`, `RankTwoScalarAux`, or `RankFourAux` . -* **Material Properties**: Adds material properties for tensor component and quantity outputs . -* **Global Strain Contribution**: Can couple the `GlobalStrain` system . -* **Homogenization Constraints**: For the new kernel system, it can add objects required to impose homogenization constraints . - -The `QuasiStaticSolidMechanicsPhysics::act()` method contains the logic for creating these objects based on the current task . - -## 3. How does an Action read parameters from the input file and create multiple objects behind the scenes? - -An `Action` reads parameters from the input file through its `InputParameters` object, which is populated during the parsing phase . The `MooseApp`'s `Parser` creates an abstract syntax tree from the input file, and the `Builder` then walks this tree to create `Action` objects, populating their `InputParameters` . - -To create multiple objects, an `Action`'s `act()` method uses the `_factory` (an instance of `Factory`) to get valid parameters for the objects it intends to create, and then calls methods on the `_problem` (an instance of `FEProblemBase`) or `_action_factory` to add these objects to the simulation . - -For example, in `QuasiStaticSolidMechanicsPhysics::act()`, when the `_current_task` is "add_variable", it retrieves valid parameters for a `MooseVariable` using `_factory.getValidParams("MooseVariable")` and then adds the variable to the problem using `_problem->addVariable("MooseVariable", disp, params)` . - -## 4. The Action warehouse: how are Actions ordered and executed? - -The `ActionWarehouse` is responsible for storing, ordering, and executing `Action` instances . - -**Ordering:** -Actions are ordered based on tasks and their registered dependencies . The `Syntax` class manages these tasks and their dependencies . The `ActionWarehouse::build()` method sorts the tasks using `_syntax.getSortedTask()` and then builds actions for each task . - -**Execution:** -The `MooseApp::run()` method orchestrates the execution flow, which includes `ActionWarehouse::executeAllActions()` . During execution, `Actions` can dynamically add other `Actions` to the warehouse (meta-Actions), which will then be executed if their associated task has not already passed . - -The execution order can be debugged using the `show_actions` and `show_action_dependencies` parameters in the `[Debug]` block of the input file . - -## 5. Syntax association: how does `[Modules/TensorMechanics/Master]` in the input file map to the `TensorMechanicsAction` class? - -The mapping from input file syntax like `[Modules/TensorMechanics/Master]` to a specific `Action` class (e.g., `QuasiStaticSolidMechanicsPhysics` which replaced `TensorMechanicsAction`) is handled by the `Syntax` system and `ActionFactory` . - -1. **Registration**: `Action` classes are registered with the `ActionFactory` and `Syntax` system. This involves associating an `Action` class with one or more tasks and defining the input file syntax that triggers its creation . For example, `registerSyntax("SetupMeshCompleteAction", "Mesh")` associates the `SetupMeshCompleteAction` with the `Mesh` block in the input file . -2. **Parsing**: The `Parser` reads the input file and creates an abstract syntax tree (`hit::Node` tree) . -3. **Building Actions**: The `Builder` walks this syntax tree. When it encounters a block that matches a registered syntax, it instructs the `ActionFactory` to create an instance of the associated `Action` class . The `ActionFactory::create()` method is responsible for instantiating the `Action` and populating its `InputParameters` . - -For the specific case of `[Modules/TensorMechanics/Master]`, it was deprecated and replaced by `[Physics/SolidMechanics/QuasiStatic]` . The `SolidMechanicsApp::registerAll` method includes calls to `registerDeprecatedSyntax` to handle the old syntax and map it to the new `QuasiStaticSolidMechanicsPhysics` action . - -## 6. Custom Actions: how to write a new Action that auto-generates a set of objects? - -To write a new `Action` that auto-generates a set of objects, you need to: - -1. **Derive from `Action` or `MooseObjectAction`**: If your action will create MOOSE objects from input file syntax, derive from `MooseObjectAction`. Otherwise, derive from `Action` . - ` ` `cpp - #include "MooseObjectAction.h" // Or "Action.h" - - class MyCustomAction : public MooseObjectAction - { - public: - static InputParameters validParams(); - MyCustomAction(const InputParameters & params); - virtual void act() override; - }; - ` ` ` -2. **Define `validParams()`**: Implement a static `validParams()` method to register the parameters your `Action` will accept from the input file . - ` ` `cpp - InputParameters - MyCustomAction::validParams() - { - InputParameters params = MooseObjectAction::validParams(); - params.addRequiredParam("my_object_name", "Name for the object to be created."); - params.addParam("some_value", 1.0, "A value for the object."); - return params; - } - ` ` ` -3. **Implement the Constructor**: The constructor will receive the `InputParameters` for your action . - ` ` `cpp - MyCustomAction::MyCustomAction(const InputParameters & params) - : MooseObjectAction(params) - { - } - ` ` ` -4. **Implement `act()`**: This is where you define the logic for creating objects. You will typically use `_factory.getValidParams()` to get default parameters for the objects you want to create, modify them with values from your action's parameters, and then use methods like `_problem->addVariable()`, `_problem->addKernel()`, etc., to add the objects to the simulation - -Wiki pages you might want to explore: -- [Core Application Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#2) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-action-system.md b/packages/akms/src/akms/_bundled/global_nodes/moose-action-system.md deleted file mode 100644 index 6e7e802..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-action-system.md +++ /dev/null @@ -1,274 +0,0 @@ ---- -id: moose-action-system -title: MOOSE Action System — Input File to Object Graph -domain: architecture -subdomain: procedural -tags: -- action -- input-file -- tensor-mechanics-action -- object-composition -- global-params -- syntax-tree -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-object-factory - type: requires - weight: 0.6 - note: Uses MOOSE object factory and registration pattern -- to: moose-object-factory - type: requires - weight: 0.9 - note: Actions create objects via factory -- to: tgs-dom-fem - type: implements - weight: 0.5 - note: Actions auto-generate FEM kernels and strain/stress objects ---- - -# MOOSE Action System — Input File to Object Graph - -Framework knowledge node covering 2 aspect(s) of Action System — Input File to Object Graph. - -## MOOSE Action system and automatic object creation - -MOOSE's Action system is a core component that translates high-level input file blocks into the low-level objects required for a simulation . This system uses `Action` classes to orchestrate the creation and configuration of various MOOSE objects like `Kernels`, `Variables`, and `Materials` based on user input . The `ActionWarehouse` manages the ordering and execution of these `Action`s, ensuring proper setup of the simulation . - -## 1. What is an `Action`? How does it differ from the objects it creates? - -An `Action` is a C++ class that performs setup tasks, often involving the creation of MOOSE objects . It differs from the objects it creates in that an `Action` is a temporary construct used during the input file parsing and setup phase, whereas the objects it creates (e.g., `Kernels`, `Variables`, `Materials`) are the actual components that constitute the simulation problem and persist throughout the simulation's lifetime . - -The base class for all actions is `Action` . A specialized type, `MooseObjectAction`, is used when the action's primary purpose is to create other MOOSE objects from an input file . The `act()` method is the core of an `Action`, where the logic for creating objects or performing other setup tasks is implemented . - -## 2. `TensorMechanics/Master` action (now `Physics/SolidMechanics/QuasiStatic`): what objects does it auto-generate? - -The `Physics/SolidMechanics/QuasiStatic` action (formerly `TensorMechanics/Master`) is a high-level action that auto-generates a suite of low-level MOOSE objects to set up a quasi-static solid mechanics problem . - -This action can generate: -* **Stress Divergence Kernels**: For calculating stress divergence equilibrium, with options for `StressDivergenceTensors`, `WeakPlaneStress`, `StressDivergenceRZTensors`, or `StressDivergenceRSphericalTensors` in the old kernel system . For the new Lagrangian kernel system, it generates `TotalLagrangianStressDivergence` or `UpdatedLagrangianStressDivergence` . -* **Displacement Variables**: Adds `Variables` for displacement fields . -* **Strain Calculators**: Depending on the `strain` parameter, it can add `ComputeFiniteStrain`, `ComputePlaneFiniteStrain`, `ComputeAxisymmetric1DFiniteStrain`, `ComputeAxisymmetricRZFiniteStrain`, `ComputeSmallStrain`, `ComputePlaneSmallStrain`, `ComputeAxisymmetric1DSmallStrain`, `ComputeAxisymmetricRZSmallStrain`, `ComputeIncrementalStrain`, `ComputePlaneIncrementalStrain`, `ComputeAxisymmetric1DIncrementalStrain`, or `ComputeAxisymmetricRZIncrementalStrain` . For the new Lagrangian system, it uses `ComputeLagrangianStrain` . -* **AuxVariables and AuxKernels**: For outputting various tensor components and quantities, such as `RankTwoAux`, `RankTwoScalarAux`, or `RankFourAux` . -* **Material Properties**: Adds material properties for tensor component and quantity outputs . -* **Global Strain Contribution**: Can couple the `GlobalStrain` system . -* **Homogenization Constraints**: For the new kernel system, it can add objects required to impose homogenization constraints . - -The `QuasiStaticSolidMechanicsPhysics::act()` method contains the logic for creating these objects based on the current task . - -## 3. How does an Action read parameters from the input file and create multiple objects behind the scenes? - -An `Action` reads parameters from the input file through its `InputParameters` object, which is populated during the parsing phase . The `MooseApp`'s `Parser` creates an abstract syntax tree from the input file, and the `Builder` then walks this tree to create `Action` objects, populating their `InputParameters` . - -To create multiple objects, an `Action`'s `act()` method uses the `_factory` (an instance of `Factory`) to get valid parameters for the objects it intends to create, and then calls methods on the `_problem` (an instance of `FEProblemBase`) or `_action_factory` to add these objects to the simulation . - -For example, in `QuasiStaticSolidMechanicsPhysics::act()`, when the `_current_task` is "add_variable", it retrieves valid parameters for a `MooseVariable` using `_factory.getValidParams("MooseVariable")` and then adds the variable to the problem using `_problem->addVariable("MooseVariable", disp, params)` . - -## 4. The Action warehouse: how are Actions ordered and executed? - -The `ActionWarehouse` is responsible for storing, ordering, and executing `Action` instances . - -**Ordering:** -Actions are ordered based on tasks and their registered dependencies . The `Syntax` class manages these tasks and their dependencies . The `ActionWarehouse::build()` method sorts the tasks using `_syntax.getSortedTask()` and then builds actions for each task . - -**Execution:** -The `MooseApp::run()` method orchestrates the execution flow, which includes `ActionWarehouse::executeAllActions()` . During execution, `Actions` can dynamically add other `Actions` to the warehouse (meta-Actions), which will then be executed if their associated task has not already passed . - -The execution order can be debugged using the `show_actions` and `show_action_dependencies` parameters in the `[Debug]` block of the input file . - -## 5. Syntax association: how does `[Modules/TensorMechanics/Master]` in the input file map to the `TensorMechanicsAction` class? - -The mapping from input file syntax like `[Modules/TensorMechanics/Master]` to a specific `Action` class (e.g., `QuasiStaticSolidMechanicsPhysics` which replaced `TensorMechanicsAction`) is handled by the `Syntax` system and `ActionFactory` . - -1. **Registration**: `Action` classes are registered with the `ActionFactory` and `Syntax` system. This involves associating an `Action` class with one or more tasks and defining the input file syntax that triggers its creation . For example, `registerSyntax("SetupMeshCompleteAction", "Mesh")` associates the `SetupMeshCompleteAction` with the `Mesh` block in the input file . -2. **Parsing**: The `Parser` reads the input file and creates an abstract syntax tree (`hit::Node` tree) . -3. **Building Actions**: The `Builder` walks this syntax tree. When it encounters a block that matches a registered syntax, it instructs the `ActionFactory` to create an instance of the associated `Action` class . The `ActionFactory::create()` method is responsible for instantiating the `Action` and populating its `InputParameters` . - -For the specific case of `[Modules/TensorMechanics/Master]`, it was deprecated and replaced by `[Physics/SolidMechanics/QuasiStatic]` . The `SolidMechanicsApp::registerAll` method includes calls to `registerDeprecatedSyntax` to handle the old syntax and map it to the new `QuasiStaticSolidMechanicsPhysics` action . - -## 6. Custom Actions: how to write a new Action that auto-generates a set of objects? - -To write a new `Action` that auto-generates a set of objects, you need to: - -1. **Derive from `Action` or `MooseObjectAction`**: If your action will create MOOSE objects from input file syntax, derive from `MooseObjectAction`. Otherwise, derive from `Action` . - ` ` `cpp - #include "MooseObjectAction.h" // Or "Action.h" - - class MyCustomAction : public MooseObjectAction - { - public: - static InputParameters validParams(); - MyCustomAction(const InputParameters & params); - virtual void act() override; - }; - ` ` ` -2. **Define `validParams()`**: Implement a static `validParams()` method to register the parameters your `Action` will accept from the input file . - ` ` `cpp - InputParameters - MyCustomAction::validParams() - { - InputParameters params = MooseObjectAction::validParams(); - params.addRequiredParam("my_object_name", "Name for the object to be created."); - params.addParam("some_value", 1.0, "A value for the object."); - return params; - } - ` ` ` -3. **Implement the Constructor**: The constructor will receive the `InputParameters` for your action . - ` ` `cpp - MyCustomAction::MyCustomAction(const InputParameters & params) - : MooseObjectAction(params) - { - } - ` ` ` -4. **Implement `act()`**: This is where you define the logic for creating objects. You will typically use `_factory.getValidParams()` to get default parameters for the objects you want to create, modify them with values from your action's parameters, and then use methods like `_problem->addVariable()`, `_problem->addKernel()`, etc., to add the objects to the simulation - -Wiki pages you might want to explore: -- [Core Application Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#2) - - -## Input file structure and block composition - -The MOOSE input file uses a hierarchical block structure to define a simulation, with top-level blocks like `[Mesh]`, `[Variables]`, `[Kernels]`, `[BCs]`, `[Materials]`, `[Executioner]`, and `[Outputs]` each responsible for specific aspects of the simulation setup . The input file is parsed into an Action/object hierarchy, where the `Parser` creates an abstract syntax tree, the `Builder` creates `Action` objects, and the `ActionWarehouse` executes these `Action`s to construct MOOSE objects via the `Factory` . - -## Top-Level Blocks and Their Responsibilities - -MOOSE input files are structured into blocks, with capital-letter blocks representing system-defined syntax . The essential top-level blocks are: - -* **`[Mesh]`**: Defines the geometry of the computational domain, often using mesh generator objects like `GeneratedMesh` . -* **`[Variables]`**: Declares the unknown field variables that the simulation will solve for . -* **`[Kernels]`**: Specifies the partial differential equations (PDEs) to be solved by adding `Kernel` objects, which represent the volumetric terms of the weak form . -* **`[BCs]`**: Defines the boundary conditions for the problem, such as Dirichlet or Neumann conditions, applied to specific boundaries of the mesh . -* **`[Materials]`**: Used to define material properties, which can be constant or depend on other variables . -* **`[Executioner]`**: Controls how the simulation progresses, including time-stepping schemes for transient problems or solver settings for steady-state problems . -* **`[Outputs]`**: Specifies how the simulation results are written, including format (e.g., ExodusII, CSV) and frequency . - -## Sub-blocks and the Type System - -Within top-level blocks, sub-blocks are used to define individual MOOSE objects . The `type = DirichletBC` syntax inside a `[BCs]` block invokes the factory system . The `Factory` is responsible for creating physics objects (Kernels, BCs, Materials, etc.) based on the `type` parameter specified in the input file . When `type = DirichletBC` is encountered, the `Factory` looks up the registered `DirichletBC` class and instantiates an object of that type, passing the parameters defined within its sub-block . - -## Block-Level Parameters vs. Object-Level Parameters - -Parameters can be defined at different levels within the input file hierarchy. -* **Block-level parameters** apply to the entire block. For example, `active` and `inactive` lists can be defined at the block level to control which sub-blocks are processed . -* **Object-level parameters** are specific to a particular MOOSE object defined within a sub-block. These parameters configure the behavior of that individual object, such as `variable` or `boundary` for a `DirichletBC` object . - -## `active`/`inactive` Lists for Toggling Objects - -The `active` and `inactive` parameters allow for selective processing of sub-blocks within an input file . -* `active`: If specified, only the sub-blocks named in this list will be visited and made active . -* `inactive`: If specified, sub-blocks matching these identifiers will be skipped . -These parameters are processed by the `Builder` during input file parsing . - -## The `[GlobalParams]` Block - -The `[GlobalParams]` block is used to define parameters that can be propagated to all objects in the simulation . While not explicitly detailed in the provided snippets, the `GlobalParamsAction` is involved in handling these parameters . This mechanism allows for setting common parameters once and having them applied universally, simplifying input files for complex simulations. - -## Include Files and Input File Inheritance - -MOOSE supports including other input files using the `!include` syntax . This allows for modular input files and can be used in any nested context . Functionally, including a file is equivalent to inserting its text at the `!include` location . Parameters from included files do not override parent parameters by default, and explicit override syntax (`:=` or `:override=`) is needed to change previously defined values . - -## Input File Parsing into Action/Object Hierarchy - -The input file parsing process involves several key components: -1. **Parser**: The `Parser` class uses the HIT (Hierarchical Input Text) parser to read the input file and create an abstract syntax tree (AST) . The `MooseApp` orchestrates this by calling `Parser::parse()` . -2. **Builder**: The `Builder` class then walks this AST and creates `Action` objects . The `MooseApp` calls `Builder::build()` . -3. **ActionWarehouse**: The created `Action` objects are stored in the `ActionWarehouse` . The `ActionWarehouse` manages and executes these `Action`s in dependency order . -4. **Factory**: As `Action`s are executed, they interact with the `Factory` to dynamically create MOOSE objects (e.g., Kernels, BCs, Materials) based on the `type` parameter specified in the input file . - -This pipeline transforms the declarative input file into a fully configured simulation object hierarchy within the `MooseApp` . - -## Relationships - -` ` `mermaid -graph LR - InputFile["Input File
(.i file)"] - Parser["Parser"] - HitTree["hit::Node
(AST)"] - Builder["Builder"] - Actions["Action Objects"] - ActionWarehouse["ActionWarehouse"] - Factory["Factory"] - MooseObjects["MOOSE Objects
(Kernels, BCs, etc.)"] - - InputFile --> Parser - Parser --> HitTree - HitTree --> Builder - Builder --> Actions - Actions --> ActionWarehouse - ActionWarehouse --> |"executeActions"| Factory - Factory --> MooseObjects -` ` ` - - -## Complete Minimal Input File for a Mechanics Problem - -Here is a minimal MOOSE input file for a mechanics problem, annotated with the purpose of each block. This example sets up a simple diffusion problem, which is analogous to a basic mechanics problem in terms of input file structure. - -` ` `ini -# This is a minimal MOOSE input file for a mechanics-like problem (diffusion) - -[Mesh] # Defines the geometry of the simulation domain. - type = GeneratedMesh # Uses a built-in mesh generator. - dim = 2 # Specifies a 2-dimensional mesh. - nx = 10 # Number of elements in the x-direction. - ny = 10 # Number of elements in the y-direction. -[] - -[Variables] # Declares the primary unknown variables to be solved. - [u] # Defines a variable named 'u'. - family = LAGRANGE # Uses Lagrange finite elements. - order = FIRST # Specifies first-order interpolation. - [] -[] - -[Kernels] # Defines the terms of the partial differential equations. - [diff] # A sub-block for a specific kernel. - type = Diffusion # Specifies the Diffusion kernel, representing -∇²u. - variable = u # Applies this kernel to the variable 'u'. - [] -[] - -[BCs] # Defines the boundary conditions for the problem. - [left_bc] # A sub-block for a boundary condition on the 'left' boundary. - type = DirichletBC # Specifies a Dirichlet boundary condition (fixed value). - variable = u # Applies to variable 'u'. - boundary = left # Applies to the boundary named 'left'. - value = 1.0 # Sets the value of 'u' to 1.0 on the 'left' boundary. - [] - [right_bc] # A sub-block for a boundary condition on the 'right' boundary. - type = DirichletBC - variable = u - boundary = right - value = 0.0 - [] -[] - -[Executioner] # Controls the simulation process (e.g., steady-state, transient). - type = Steady # Specifies a steady-state solver. - solve_type = NEWTON # Uses Newton's method for solving the nonlinear system. -[] - -[Outputs] # Specifies how and what results are saved. - exodus = true # Enables output in ExodusII format. -[] -` ` ` - - - - - - - -## Notes - -The provided context primarily focuses on the core MOOSE framework and its input file processing. While the prompt asks for a mechanics problem, the fundamental structure of the input file and the roles of the top-level blocks remain consistent across different physics applications. The example provided uses a diffusion problem as it directly relates to the available snippets illustrating basic input file structure. The `[GlobalParams]` block is mentioned in the `Builder.C` file as `GlobalParamsAction` , indicating its role in parameter propagation, - -Wiki pages you might want to explore: -- [Core Application Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#2) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-allen-cahn-cahn-hilliard.md b/packages/akms/src/akms/_bundled/global_nodes/moose-allen-cahn-cahn-hilliard.md deleted file mode 100644 index 3e690ec..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-allen-cahn-cahn-hilliard.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -id: moose-allen-cahn-cahn-hilliard -title: MOOSE Allen-Cahn and Cahn-Hilliard Kernels — Detailed Implementation -domain: phase-field -subdomain: algorithmic -tags: -- allen-cahn -- cahn-hilliard -- split-form -- weak-form -- gradient-energy -- chemical-potential -- mobility -- AD-kernel -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-derivative-parsed-material - type: requires - weight: 0.6 - note: Uses DerivativeParsedMaterial for free energy definitions -- to: cm-phase-field-fracture - type: implements - weight: 0.7 - note: AC/CH kernels are the core discretization for all phase field models -- to: tgs-dom-fem - type: implements - weight: 0.5 - note: Allen-Cahn and Cahn-Hilliard weak forms as FEM kernels ---- - -# MOOSE Allen-Cahn and Cahn-Hilliard Kernels — Detailed Implementation - -Framework knowledge node covering 2 aspect(s) of Allen-Cahn and Cahn-Hilliard Kernels — Detailed Implementation. - -## Allen-Cahn kernel implementation details - -The Allen-Cahn kernels in MOOSE are designed to solve the Allen-Cahn equation, which describes the evolution of an order parameter ($\eta$) in phase-field models. The equation is typically split into several terms, each handled by a specific kernel for modularity. The core kernels discussed are `AllenCahn` (or `ACBulk`), `ACInterface`, and `TimeDerivative`, which together form the weak form of the Allen-Cahn equation. - -## Classes & Methods - -* `AllenCahn::validParams()`: Defines the valid input parameters for the `AllenCahn` kernel. -* `AllenCahn::AllenCahn()`: Constructor for the `AllenCahn` kernel, initializing material properties for free energy derivatives. -* `AllenCahn::initialSetup()`: Performs initial validation for nonlinear coupling and derivative material properties. -* `AllenCahn::computeDFDOP()`: Computes the derivative of the bulk free energy with respect to the order parameter for either residual or Jacobian calculations. -* `ACInterface::validParams()`: Defines the valid input parameters for the `ACInterface` kernel. -* `ACInterface::ACInterface()`: Constructor for the `ACInterface` kernel, initializing material properties for mobility and interfacial parameters, and their derivatives. -* `ACInterface::initialSetup()`: Performs initial validation for mobility and kappa material properties. -* `ACInterface::computeQpResidual()`: Computes the residual contribution of the gradient energy term at a quadrature point. -* `ACInterface::computeQpJacobian()`: Computes the Jacobian contribution of the gradient energy term at a quadrature point. -* `ADAllenCahn::validParams()`: Defines valid parameters for the AD version of the Allen-Cahn bulk kernel. -* `ADACInterface::validParams()`: Defines valid parameters for the AD version of the Allen-Cahn interface kernel. -* `ACBulk::validParams()`: Defines valid parameters for the base `ACBulk` kernel. -* `ACBulk::precomputeQpResidual()`: Computes the residual contribution for the bulk term, multiplying the mobility by the free energy derivative. -* `ADAllenCahnBase::precomputeQpResidual()`: Computes the residual for the AD bulk term, similar to `ACBulk`. - -## Equations - -The general form of the Allen-Cahn equation is: -$$ -\frac{\partial \eta_i}{\partial t} = - L \frac{\delta F}{\delta \eta_i} \quad (1) -$$ -where $F$ is the free energy functional. The free energy functional typically includes local and gradient energy terms: -$$ -F = \int_V f_{loc}(\eta_0, \eta_1, \ldots, \eta_N) + f_{add} (\eta_0, \eta_1, \ldots, \eta_N) + \kappa \sum^N_i |\nabla \eta_i|^2 \quad (2) -$$ - -The weak form of the Allen-Cahn equation, without boundary terms, is given by: -$$ -\boldsymbol{\mathcal{R}}_{\eta_i} = \left( \frac{\partial \eta_j}{\partial t}, \psi_m \right) + \left( \nabla(\kappa_j\eta_j), \nabla (L\psi_m) \right) + L \left( \frac{\partial f_{loc}}{\partial \eta_j} + \frac{\partial E_d}{\partial \eta_j}, \psi_m \right) \quad (3) -$$ -This residual is split into three parts, each handled by a specific kernel. - -### 1. `AllenCahn` kernel: what weak form does it implement? ∫ L·∂f/∂η·ψ dΩ? - -The `AllenCahn` kernel implements the bulk or local energy term of the Allen-Cahn equation. Its contribution to the residual is: -$$ -L \left( \frac{\partial f_{loc}}{\partial \eta_j} + \frac{\partial E_d}{\partial \eta_j}, \psi_m \right) \quad (4) -$$ -This corresponds to $\int L \cdot \frac{\partial f}{\partial \eta} \cdot \psi \, d\Omega$, where $f$ represents the local free energy density ($f_{loc} + E_d$). -The `AllenCahn` class inherits from `ACBulk` and uses a `DerivativeMaterial` to obtain the free energy derivatives. -The `computeDFDOP` method returns the derivative of the free energy with respect to the order parameter, $\frac{\partial F}{\partial \eta}$, for the residual calculation. -The `precomputeQpResidual` method in `ACBulk` then multiplies this by the mobility $L$. - -### 2. `ACInterface` kernel: the gradient energy term ∫ κ·∇η·∇ψ dΩ — how is κ specified? - -The `ACInterface` kernel implements the gradient energy term. Its contribution to the residual is: -$$ -\left( \nabla(\kappa_j\eta_j), \nabla (L\psi_m) \right) \quad (5) -$$ -This term is derived from $\int \kappa \nabla \eta \cdot \nabla (L\psi) \, d\Omega$. -The parameter $\kappa$ (interfacial parameter) is specified as a `MaterialProperty` named `kappa_name` in the input file. It can be a constant value or a function of MOOSE variables. -The `ACInterface` kernel retrieves $\kappa$ using `getMaterialProperty("kappa_name")`. - -### 3. `TimeDerivative` for ∂η/∂t - -The `TimeDerivative` kernel implements the transient term of the Allen-Cahn equation. Its contribution to the residual is: -$$ -\left( \frac{\partial \eta_j}{\partial t}, \psi_m \right) \quad (6) -$$ -This term is standard in MOOSE for time-dependent problems. - -### 4. How do these three kernels combine to solve ∂η/∂t = -L·(∂f/∂η - κ∇²η)? - -The three kernels (`TimeDerivative`, `AllenCahn`, and `ACInterface`) combine to solve the weak form of the Allen-Cahn equation. The strong form of the equation is: -$$ -\frac{\partial \eta}{\partial t} = -L \left( \frac{\partial f}{\partial \eta} - \nabla \cdot (\kappa \nabla \eta) \right) \quad (7) -$$ -Rearranging this to a residual form for finite element solution: -$$ -\mathcal{R} = \frac{\partial \eta}{\partial t} + L \frac{\partial f}{\partial \eta} - L \nabla \cdot (\kappa \nabla \eta) = 0 \quad (8) -$$ -Multiplying by a test function $\psi$ and integrating over the domain $\Omega$: -$$ -\int_\Omega \left( \frac{\partial \eta}{\partial t} \right) \psi \, d\Omega + \int_\Omega L \frac{\partial f}{\partial \eta} \psi \, d\Omega - \int_\Omega L \nabla \cdot (\kappa \nabla \eta) \psi \, d\Omega = 0 \quad (9) -$$ -Applying integration by parts to the third term (gradient energy term): -$$ -- \int_\Omega L \nabla \cdot (\kappa \nabla \eta) \psi \, d\Omega = \int_\Omega L \kappa \nabla \eta \cdot \nabla \psi \, d\Omega - \int_{\partial\Omega} L \kappa (\nabla \eta \cdot \mathbf{n}) \psi \, dS \quad (10) -$$ -Assuming natural boundary conditions (the surface integral is zero), the weak form becomes: -$$ -\left( \frac{\partial \eta}{\partial t}, \psi \right) + \left( L \frac{\partial f}{\partial \eta}, \psi \right) + \left( L \kappa \nabla \eta, \nabla \psi \right) = 0 \quad (11) -$$ -The MOOSE implementation uses a slightly different form for the gradient term, $\left( \nabla(\kappa_j\eta_j), \nabla (L\psi_m) \right)$, which is equivalent under certain assumptions or when $L$ and $\kappa$ are constants. -Each kernel contributes its part to the overall residual: -* `TimeDerivative`: $\left( \frac{\partial \eta_j}{\partial t}, \psi_m \right)$ -* `AllenCahn`: $L \left( \frac{\partial f_{loc}}{\partial \eta_j} + \frac{\partial E_d}{\partial \eta_j}, \psi_m \right)$ -* `ACInterface`: $\left( \nabla(\kappa_j\eta_j), \nabla (L\psi_m) \right)$ - -These terms are summed up by the MOOSE framework to form the complete residual equation for the order parameter $\eta$. - -### 5. `ACBulk` vs `AllenCahn` — is there a difference? - -`ACBulk` is a templated base class for the bulk or local energy term of the Allen-Cahn equation. It handles the mobility `L` and its derivatives. -`AllenCahn` is a concrete implementation that inherits from `ACBulk`. It specifically uses a `DerivativeMaterial` to obtain the free energy function and its derivatives. -Therefore, `ACBulk` provides the general framework for the bulk term, while `AllenCahn` is a specific kernel that uses a `DerivativeParsedMaterial` for the free energy. - -### 6. AD versions: `ADAllenCahn`, `ADACInterface` — advantages? - -`ADAllenCahn` and `ADACInterface` are the Automatic Differentiation (AD) versions of the `AllenCahn` and `ACInterface` kernels, respectively. -The primary advantage of using AD kernels is that they automatically compute the Jacobian terms required for Newton's method, which is used to solve the nonlinear system of equations. This eliminates the need for manual derivation and implementation of complex Jacobian expressions, reducing the potential for errors and simplifying code maintenance. -For example, `ADACInterface` inherits from `ADKernel` and `DerivativeMaterialPropertyNameInterface` - - -## Cahn-Hilliard kernel implementation details - -The MOOSE framework provides two primary implementations for the Cahn-Hilliard equation: a direct form and a split form. The direct form uses the `CahnHilliard` and `CHInterface` kernels to solve the fourth-order equation directly, while the split form decomposes the problem into two second-order equations solved by `SplitCHParsed` and `SplitCHWRes` kernels. The split form is generally preferred due to improved convergence properties and avoidance of C1 continuity requirements. - -## 1. Direct Form: `CahnHilliard` kernel — the biharmonic $\nabla^4 c$ problem — how handled? - -The direct form of the Cahn-Hilliard equation is solved using a combination of kernels, primarily `CahnHilliard` and `CHInterface` . The full weak form for the direct solution of the Cahn-Hilliard equation is given by: -$$ -\boldsymbol{\mathcal{R}}_{c_i} = \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( \kappa_i \nabla^2 c_i, \nabla \cdot (M_i \nabla \psi_m ) \right) + \left( M_i \left( \nabla \frac{\partial f_{loc} }{\partial c_i} + \nabla \frac{\partial E_d}{\partial c_i} \right), \nabla \psi_m \right) \quad (1) -$$ - -The `CahnHilliard` kernel implements the bulk free energy term : -$$ -\left(M \sum_j\nabla c_j\frac{\partial^2 f}{\partial c_i c_j}, \nabla \psi\right) -$$ -This corresponds to the term $\left( M_i \left( \nabla \frac{\partial f_{loc} }{\partial c_i} + \nabla \frac{\partial E_d}{\partial c_i} \right), \nabla \psi_m \right)$ in Equation (1) . - -The `CHInterface` kernel handles the gradient energy term : -$$ -\left( \kappa_i \nabla^2 c_i, \nabla \cdot (M_i \nabla \psi_m ) \right) -$$ -This term involves second-order derivatives of the concentration variable, which, when combined with the test function's derivatives, effectively addresses the biharmonic nature of the direct Cahn-Hilliard equation. - -## 2. Split Form: separate equations for $\mu$ and $c$ — `SplitCHParsed` + `SplitCHWRes` — what does each solve? - -The split form of the Cahn-Hilliard equation introduces an auxiliary variable, the chemical potential $\mu$, to break down the fourth-order equation into two coupled second-order equations . The two residual equations in weak form are: -$$ -\begin{aligned} - \boldsymbol{\mathcal{R}}_{\mu_i} &=& \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( M_i \nabla \mu_i, \nabla \psi_m \right) \\ - \boldsymbol{\mathcal{R}}_{c_i} &=& \left( \left( -\kappa_i \nabla^2 c_i + \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \mu_i \right), \psi_m \right) -\end{aligned} \quad (2) -$$ - -* **`SplitCHWRes`**: This kernel contributes to the residual equation for the chemical potential $\mu$ . Specifically, it implements the term $\left( M_i \nabla \mu_i, \nabla \psi_m \right)$ from the first equation in (2) . It takes the mobility `mob_name` as a parameter . -* **`SplitCHParsed`**: This kernel contributes to the residual equation for the concentration $c$ . It implements the term $\left( \left( -\kappa_i \nabla^2 c_i + \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \mu_i \right), \psi_m \right)$ from the second equation in (2) . It requires the free energy function name `f_name`, the gradient energy coefficient `kappa_name`, and the chemical potential variable `w` (which represents $\mu$) . - -## 3. Why is the split form preferred? Avoids C1 continuity requirements? - -The split form is preferred because it improves solve convergence . While the documentation doesn't explicitly state "avoids C1 continuity requirements," the decomposition of the fourth-order equation into two second-order equations inherently relaxes the continuity requirements for the finite element basis functions. Solving a fourth-order PDE directly typically requires C1 continuous basis functions (i.e., functions whose first derivatives are also continuous), which are more complex to implement and computationally more expensive than the C0 continuous basis functions (only the function itself is continuous) sufficient for second-order PDEs. - -## 4. The chemical potential variable $\mu$: how is it defined as $\mu = \partial f/\partial c$? - -In the split form, the chemical potential $\mu$ is implicitly defined through the second residual equation in (2) . The term $\left( \left( -\kappa_i \nabla^2 c_i + \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \mu_i \right), \psi_m \right)$ effectively enforces the relationship: -$$ -\mu_i = \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \kappa_i \nabla^2 c_i \quad (3) -$$ -This equation defines $\mu_i$ as the variational derivative of the total free energy with respect to $c_i$. The `SplitCHParsed` kernel uses the free energy function and its derivatives, typically provided by a `DerivativeParsedMaterial`, to compute the $\frac{\partial f_{loc}}{\partial c_i}$ and $\frac{\partial E_d}{\partial c_i}$ terms . - -## 5. `CHInterface` kernel for the gradient energy: $\int \kappa \cdot \nabla c \cdot \nabla \psi \, d\Omega$ - -The `CHInterface` kernel implements the interfacial or gradient energy term of the Cahn-Hilliard equation . In the direct form, this corresponds to the term $\left( \kappa_i \nabla^2 c_i, \nabla \cdot (M_i \nabla \psi_m ) \right)$ in Equation (1) . The `computeQpResidual` method in `CHInterfaceBase` shows the calculation of this residual term . - -## 6. Mobility in Cahn-Hilliard: `CoupledMaterialDerivative` or how $\nabla \cdot (M \nabla \mu)$ is discretized - -The mobility term $\nabla \cdot (M \nabla \mu)$ appears in the strong form of the Cahn-Hilliard equation. In the weak form for the split formulation, this term becomes $\left( M_i \nabla \mu_i, \nabla \psi_m \right)$ . This term is implemented by the `SplitCHWRes` kernel . The `computeQpResidual` method in `ADSplitCHWResBase` (an AD version of `SplitCHWResBase`) shows the calculation of this term as `_mob[_qp] * _grad_u[_qp]` , where `_grad_u` is the gradient of the variable the kernel is operating on (which is $\mu$ in this case) and `_mob` is the mobility material property. - -## 7. Variable mobility: $M(c)$ — how its derivative enters the Jacobian - -When the mobility $M$ is a function of concentration $c$, i.e., $M(c)$, its derivative with respect to $c$ enters the Jacobian. In the `CHInterfaceBase` kernel, which is used in the direct formulation, the `computeQpJacobian` method explicitly includes terms involving derivatives of the mobility, such as `_dMdc` and `_d2Mdc2` . These represent $\frac{\partial M}{\partial c}$ and $\frac{\partial^2 M}{\partial c^2}$ respectively. Similarly, for coupled variables, `_dMdarg` and `_d2Mdcdarg` are used . - -In the split form, for the `SplitCHWResBase` kernel, if the mobility `_mob` depends on coupled variables, its derivatives `_dmobdarg` are used in `computeQpOffDiagJacobian` to calculate the off-diagonal Jacobian entries . - -## Classes & Methods - -* `CahnHilliard::CahnHilliard()`: Implements the bulk free energy term for the direct Cahn-Hilliard formulation. -* `CHInterface::CHInterface()`: Implements the gradient energy term for the direct Cahn-Hilliard formulation. -* `SplitCHParsed::SplitCHParsed()`: Implements the concentration residual equation in the split Cahn-Hilliard formulation, including free energy and gradient terms. -* `SplitCHWRes::SplitCHWRes()`: Implements the chemical potential residual equation in the split Cahn-Hilliard formulation, including the mobility term. -* `CHInterfaceBase::computeQpResidual()`: Calculates the residual for the gradient energy term in the direct Cahn-Hilliard equation. -* `CHInterfaceBase::computeQpJacobian()`: Calculates the Jacobian for the gradient energy term, including mobility derivatives. -* `ADSplitCHWResBase::precomputeQpResidual()`: Calculates the residual for the chemical potential equation in the split Cahn-Hilliard formulation. -* `SplitCHWResBase::computeQpOffDiagJacobian()`: Calculates off-diagonal Jacobian entries for the chemical potential equation, considering mobility derivatives. -* `SplitCHCRes::computeQpResidual()`: Calculates the residual for the concentration equation in the split Cahn-Hilliard formulation. -* `SplitCHCRes::computeQpJacobian()`: Calculates the Jacobian for the concentration equation. -* `SplitCHCRes::computeQpOffDiagJacobian()`: Calculates off-diagonal Jacobian entries for the concentration equation. - -## Equations - -**Direct Cahn-Hilliard Weak Form:** -$$ -\boldsymbol{\mathcal{R}}_{c_i} = \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( \kappa_i \nabla^2 c_i, \nabla \cdot ( - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-allen-cahn-kernels.md b/packages/akms/src/akms/_bundled/global_nodes/moose-allen-cahn-kernels.md deleted file mode 100644 index 7e49230..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-allen-cahn-kernels.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: moose-allen-cahn-kernels -title: MOOSE Allen-Cahn kernel implementation details -domain: phase-field -subdomain: algorithmic -tags: -- allen-cahn -- ACInterface -- gradient-energy -- mobility -- weak-form -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-allen-cahn-cahn-hilliard - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-allen-cahn-cahn-hilliard ---- - -# MOOSE Allen-Cahn kernel implementation details - -The Allen-Cahn kernels in MOOSE are designed to solve the Allen-Cahn equation, which describes the evolution of an order parameter ($\eta$) in phase-field models. The equation is typically split into several terms, each handled by a specific kernel for modularity. The core kernels discussed are `AllenCahn` (or `ACBulk`), `ACInterface`, and `TimeDerivative`, which together form the weak form of the Allen-Cahn equation. - -## Classes & Methods - -* `AllenCahn::validParams()`: Defines the valid input parameters for the `AllenCahn` kernel. -* `AllenCahn::AllenCahn()`: Constructor for the `AllenCahn` kernel, initializing material properties for free energy derivatives. -* `AllenCahn::initialSetup()`: Performs initial validation for nonlinear coupling and derivative material properties. -* `AllenCahn::computeDFDOP()`: Computes the derivative of the bulk free energy with respect to the order parameter for either residual or Jacobian calculations. -* `ACInterface::validParams()`: Defines the valid input parameters for the `ACInterface` kernel. -* `ACInterface::ACInterface()`: Constructor for the `ACInterface` kernel, initializing material properties for mobility and interfacial parameters, and their derivatives. -* `ACInterface::initialSetup()`: Performs initial validation for mobility and kappa material properties. -* `ACInterface::computeQpResidual()`: Computes the residual contribution of the gradient energy term at a quadrature point. -* `ACInterface::computeQpJacobian()`: Computes the Jacobian contribution of the gradient energy term at a quadrature point. -* `ADAllenCahn::validParams()`: Defines valid parameters for the AD version of the Allen-Cahn bulk kernel. -* `ADACInterface::validParams()`: Defines valid parameters for the AD version of the Allen-Cahn interface kernel. -* `ACBulk::validParams()`: Defines valid parameters for the base `ACBulk` kernel. -* `ACBulk::precomputeQpResidual()`: Computes the residual contribution for the bulk term, multiplying the mobility by the free energy derivative. -* `ADAllenCahnBase::precomputeQpResidual()`: Computes the residual for the AD bulk term, similar to `ACBulk`. - -## Equations - -The general form of the Allen-Cahn equation is: -$$ -\frac{\partial \eta_i}{\partial t} = - L \frac{\delta F}{\delta \eta_i} \quad (1) -$$ -where $F$ is the free energy functional. The free energy functional typically includes local and gradient energy terms: -$$ -F = \int_V f_{loc}(\eta_0, \eta_1, \ldots, \eta_N) + f_{add} (\eta_0, \eta_1, \ldots, \eta_N) + \kappa \sum^N_i |\nabla \eta_i|^2 \quad (2) -$$ - -The weak form of the Allen-Cahn equation, without boundary terms, is given by: -$$ -\boldsymbol{\mathcal{R}}_{\eta_i} = \left( \frac{\partial \eta_j}{\partial t}, \psi_m \right) + \left( \nabla(\kappa_j\eta_j), \nabla (L\psi_m) \right) + L \left( \frac{\partial f_{loc}}{\partial \eta_j} + \frac{\partial E_d}{\partial \eta_j}, \psi_m \right) \quad (3) -$$ -This residual is split into three parts, each handled by a specific kernel. - -### 1. `AllenCahn` kernel: what weak form does it implement? ∫ L·∂f/∂η·ψ dΩ? - -The `AllenCahn` kernel implements the bulk or local energy term of the Allen-Cahn equation. Its contribution to the residual is: -$$ -L \left( \frac{\partial f_{loc}}{\partial \eta_j} + \frac{\partial E_d}{\partial \eta_j}, \psi_m \right) \quad (4) -$$ -This corresponds to $\int L \cdot \frac{\partial f}{\partial \eta} \cdot \psi \, d\Omega$, where $f$ represents the local free energy density ($f_{loc} + E_d$). -The `AllenCahn` class inherits from `ACBulk` and uses a `DerivativeMaterial` to obtain the free energy derivatives. -The `computeDFDOP` method returns the derivative of the free energy with respect to the order parameter, $\frac{\partial F}{\partial \eta}$, for the residual calculation. -The `precomputeQpResidual` method in `ACBulk` then multiplies this by the mobility $L$. - -### 2. `ACInterface` kernel: the gradient energy term ∫ κ·∇η·∇ψ dΩ — how is κ specified? - -The `ACInterface` kernel implements the gradient energy term. Its contribution to the residual is: -$$ -\left( \nabla(\kappa_j\eta_j), \nabla (L\psi_m) \right) \quad (5) -$$ -This term is derived from $\int \kappa \nabla \eta \cdot \nabla (L\psi) \, d\Omega$. -The parameter $\kappa$ (interfacial parameter) is specified as a `MaterialProperty` named `kappa_name` in the input file. It can be a constant value or a function of MOOSE variables. -The `ACInterface` kernel retrieves $\kappa$ using `getMaterialProperty("kappa_name")`. - -### 3. `TimeDerivative` for ∂η/∂t - -The `TimeDerivative` kernel implements the transient term of the Allen-Cahn equation. Its contribution to the residual is: -$$ -\left( \frac{\partial \eta_j}{\partial t}, \psi_m \right) \quad (6) -$$ -This term is standard in MOOSE for time-dependent problems. - -### 4. How do these three kernels combine to solve ∂η/∂t = -L·(∂f/∂η - κ∇²η)? - -The three kernels (`TimeDerivative`, `AllenCahn`, and `ACInterface`) combine to solve the weak form of the Allen-Cahn equation. The strong form of the equation is: -$$ -\frac{\partial \eta}{\partial t} = -L \left( \frac{\partial f}{\partial \eta} - \nabla \cdot (\kappa \nabla \eta) \right) \quad (7) -$$ -Rearranging this to a residual form for finite element solution: -$$ -\mathcal{R} = \frac{\partial \eta}{\partial t} + L \frac{\partial f}{\partial \eta} - L \nabla \cdot (\kappa \nabla \eta) = 0 \quad (8) -$$ -Multiplying by a test function $\psi$ and integrating over the domain $\Omega$: -$$ -\int_\Omega \left( \frac{\partial \eta}{\partial t} \right) \psi \, d\Omega + \int_\Omega L \frac{\partial f}{\partial \eta} \psi \, d\Omega - \int_\Omega L \nabla \cdot (\kappa \nabla \eta) \psi \, d\Omega = 0 \quad (9) -$$ -Applying integration by parts to the third term (gradient energy term): -$$ -- \int_\Omega L \nabla \cdot (\kappa \nabla \eta) \psi \, d\Omega = \int_\Omega L \kappa \nabla \eta \cdot \nabla \psi \, d\Omega - \int_{\partial\Omega} L \kappa (\nabla \eta \cdot \mathbf{n}) \psi \, dS \quad (10) -$$ -Assuming natural boundary conditions (the surface integral is zero), the weak form becomes: -$$ -\left( \frac{\partial \eta}{\partial t}, \psi \right) + \left( L \frac{\partial f}{\partial \eta}, \psi \right) + \left( L \kappa \nabla \eta, \nabla \psi \right) = 0 \quad (11) -$$ -The MOOSE implementation uses a slightly different form for the gradient term, $\left( \nabla(\kappa_j\eta_j), \nabla (L\psi_m) \right)$, which is equivalent under certain assumptions or when $L$ and $\kappa$ are constants. -Each kernel contributes its part to the overall residual: -* `TimeDerivative`: $\left( \frac{\partial \eta_j}{\partial t}, \psi_m \right)$ -* `AllenCahn`: $L \left( \frac{\partial f_{loc}}{\partial \eta_j} + \frac{\partial E_d}{\partial \eta_j}, \psi_m \right)$ -* `ACInterface`: $\left( \nabla(\kappa_j\eta_j), \nabla (L\psi_m) \right)$ - -These terms are summed up by the MOOSE framework to form the complete residual equation for the order parameter $\eta$. - -### 5. `ACBulk` vs `AllenCahn` — is there a difference? - -`ACBulk` is a templated base class for the bulk or local energy term of the Allen-Cahn equation. It handles the mobility `L` and its derivatives. -`AllenCahn` is a concrete implementation that inherits from `ACBulk`. It specifically uses a `DerivativeMaterial` to obtain the free energy function and its derivatives. -Therefore, `ACBulk` provides the general framework for the bulk term, while `AllenCahn` is a specific kernel that uses a `DerivativeParsedMaterial` for the free energy. - -### 6. AD versions: `ADAllenCahn`, `ADACInterface` — advantages? - -`ADAllenCahn` and `ADACInterface` are the Automatic Differentiation (AD) versions of the `AllenCahn` and `ACInterface` kernels, respectively. -The primary advantage of using AD kernels is that they automatically compute the Jacobian terms required for Newton's method, which is used to solve the nonlinear system of equations. This eliminates the need for manual derivation and implementation of complex Jacobian expressions, reducing the potential for errors and simplifying code maintenance. -For example, `ADACInterface` inherits from `ADKernel` and `DerivativeMaterialPropertyNameInterface` - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-assembly-loop.md b/packages/akms/src/akms/_bundled/global_nodes/moose-assembly-loop.md deleted file mode 100644 index 5d75b56..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-assembly-loop.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -id: moose-assembly-loop -title: MOOSE Execution Architecture — Threading and Assembly -domain: architecture -subdomain: algorithmic -tags: -- threading -- element-loop -- quadrature -- assembly -- shape-function -- automatic-differentiation -- residual -- jacobian -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-object-factory - type: requires - weight: 0.6 - note: Uses MOOSE object factory and registration pattern -- to: moose-object-factory - type: requires - weight: 0.7 - note: Assembly loop executes registered kernels/materials -- to: moose-jfnk-preconditioning - type: requires - weight: 0.7 - note: Assembly feeds into nonlinear solver -- to: tgs-dom-fem - type: implements - weight: 0.7 - note: Implements FEM assembly loop with threading and AD ---- - -# MOOSE Execution Architecture — Threading and Assembly - -Framework knowledge node covering 1 aspect(s) of Execution Architecture — Threading and Assembly. - -## Thread-level parallelism and assembly loop - -The user is asking for a detailed explanation of MOOSE's execution architecture, focusing on the assembly process. This involves understanding the call chain from `Executioner` to `ThreadedElementLoop`, the threading model, the role of per-thread `Assembly` objects, the element loop's operations, quadrature, variable coupling, automatic differentiation, and object execution ordering. - -I will address each point of your query by referencing relevant classes, methods, and concepts within the MOOSE framework. - -## Execution Architecture Overview - -MOOSE's execution architecture is centered around solving finite element problems. The `Executioner` class orchestrates the overall simulation, which typically involves a `NonlinearSystem` to handle the nonlinear solve, and an `FEProblem` that manages the finite element discretization and assembly process. The core of the assembly happens within `ThreadedElementLoop` and its derived classes, which parallelize the element-wise computations. - -### 1. `Executioner` → `NonlinearSystem` → `FEProblem` → `ThreadedElementLoop` Call Chain - -The simulation begins with an `Executioner` object, which defines the `execute()` interface for running simulations . Different types of executioners exist, such as `Steady` and `Transient`, for various simulation types . - -Within the `Executioner`, the `FEProblemSolve` object encapsulates the logic for solving the `FEProblem` . The `FEProblem` then interacts with one or more `NonlinearSystem` objects to manage the solution variables and their associated equations . - -The `NonlinearSystemBase` class is responsible for the assembly of residuals and Jacobians . This assembly process is parallelized using `ThreadedElementLoop` and its specialized derived classes, such as `NonlinearThread` . - -The call chain for assembly generally follows: -`Executioner::execute()` → `FEProblemSolve::solve()` → `FEProblem::computeResidual()` / `FEProblem::computeJacobian()` → `NonlinearSystemBase::assemble()` → `ThreadedElementLoop::operator()` . - -### 2. Threading Model: TBB or pthreads — How are element ranges split across threads? - -MOOSE leverages `libMesh` for its threading capabilities, which can utilize either TBB (Threading Building Blocks) or pthreads. The `ThreadedElementLoop` class is the base for parallelizing operations over elements . - -The `operator()` method of `ThreadedElementLoop` takes a `ConstElemRange` as input, which represents a range of elements to be processed . This range is split across available threads. Each thread then iterates over its assigned subset of elements, performing computations such as `onElement()`, `onBoundary()`, and `onInternalSide()` . The `libMesh::n_threads()` function returns the number of active threads . - -### 3. Per-thread `Assembly` objects: why one per thread? How do they avoid data races? - -MOOSE uses per-thread `Assembly` objects to avoid data races during the element assembly process . Each thread has its own `Assembly` object, which manages local data structures like `_local_re` (local residual) and `_local_ke` (local Jacobian) . - -By having a separate `Assembly` object for each thread, computations on different elements can proceed concurrently without contention for shared memory. After each thread completes its local assembly for its assigned elements, the local contributions are accumulated into the global PETSc `Mat` (matrix) and `Vec` (vector) in a thread-safe manner . This accumulation typically involves atomic operations or critical sections to ensure data integrity when updating the global sparse matrix and vector. - -### 4. The element loop: `reinit(elem)` → compute kernels → accumulate `_local_re`/`_local_ke` → add to global PETSc Mat/Vec - -The element loop, as implemented in `ThreadedElementLoop` and its derivatives like `NonlinearThread`, follows a specific sequence for each element: -1. **`reinit(elem)`**: Before processing an element, the finite element data (shape functions, Jacobians, etc.) and material properties are reinitialized for the current element. This is handled by methods like `FEProblemBase::reinitElement()` and `FEProblemBase::reinitMaterials()` . The `MooseVariableFE` objects also reinitialize their data for the current element . -2. **Compute Kernels**: The `computeOnElement()` method (or similar for boundaries/interfaces) is called, which iterates through the registered `Kernel` objects. Each `Kernel` then computes its contribution to the residual and Jacobian for the current element at each quadrature point . For example, `Kernel::computeResidual()` and `Kernel::computeJacobian()` are called . -3. **Accumulate `_local_re`/`_local_ke`**: Inside the kernel's `computeResidual()` and `computeJacobian()` methods, the contributions are added to the thread-local `_local_re` (residual vector) and `_local_ke` (Jacobian matrix) . -4. **Add to global PETSc Mat/Vec**: After all kernels have computed their contributions for an element, the `accumulate()` method (or similar) is called to add the thread-local `_local_re` and `_local_ke` to the global PETSc `Mat` and `Vec` . This is typically done using `add_vector()` and `add_matrix()` methods on the PETSc objects. - -### 5. Quadrature: `_qp` index, `_JxW[_qp]`, `_test[_i][_qp]`, `_phi[_j][_qp]` — how are shape function values cached? - -Quadrature is fundamental to numerical integration in finite element methods . MOOSE uses Gaussian quadrature to approximate integrals over elements. -- `_qp`: This is the current quadrature point index within the element . -- `_JxW[_qp]`: This array stores the product of the Jacobian determinant of the mapping from reference to physical element and the quadrature weight at each quadrature point . MOOSE automatically handles this term, so kernels only compute the integrand . -- `_test[_i][_qp]`: This represents the value of the `i`-th test function at the `_qp`-th quadrature point . -- `_phi[_j][_qp]`: This represents the value of the `j`-th trial function (shape function) at the `_qp`-th quadrature point . - -Shape function values and their gradients (`_grad_test`, `_grad_phi`) are precomputed and cached by the `Assembly` object for the current element and quadrature rule . This caching avoids redundant computations within the inner loops of kernels. The `MooseVariableData` class, which is associated with each `MooseVariableFE`, holds pointers to assembly methods that retrieve these precomputed values . - -### 6. Variable coupling: on-diagonal vs off-diagonal Jacobian blocks — how determined? - -Variable coupling determines which entries in the Jacobian matrix are non-zero. -- **On-diagonal Jacobian blocks**: These represent the derivative of a residual with respect to its own primary variable. For a `Kernel` operating on variable `u`, `computeQpJacobian()` calculates $\frac{\partial R_u}{\partial u}$ . -- **Off-diagonal Jacobian blocks**: These represent the derivative of a residual with respect to a *coupled* variable. For a `Kernel` operating on variable `u` that is coupled to variable `v`, `computeQpOffDiagJacobian(jvar_num)` calculates $\frac{\partial R_u}{\partial v}$ . The `jvar_num` argument specifies the coupled variable's number. - -The `FEProblem` maintains a list of coupled variables for each system. When a `Kernel` is created, it declares its dependencies on other variables. During assembly, the `NonlinearSystemBase` uses this coupling information to determine which `computeQpOffDiagJacobian()` methods need to be called . If a variable is not explicitly coupled, its off-diagonal Jacobian contribution is assumed to be zero. - -### 7. AD (automatic differentiation) path: `ADKernel` and `DualNumber` types — how does AD change the assembly? - -MOOSE supports Automatic Differentiation (AD) to compute Jacobians analytically, which can improve accuracy and performance compared to finite differencing. -- `ADKernel`: This is a specialized `Kernel` class designed to work with AD . -- `DualNumber` types: MOOSE uses `ADReal` (a `DualNumber` type) to represent values and their derivatives. When AD is enabled, variables and intermediate computations within kernels are performed using `ADReal` instead of `Real`. - -When AD is used, the `computeQpResidual()` method in an `ADKernel` returns an `ADReal` value, which implicitly carries the derivative information with respect to all dependent variables . This means that the `computeQpJacobian()` and `computeQpOffDiagJacobian()` methods do not need to be explicitly overridden by the user for AD kernels, as the Jacobian contributions are extracted directly from the `ADReal` residual. The `ADFunctorInterface` provides the necessary mechanisms for this . - -### 8. Object execution ordering within a thread: materials before kernels? Dependency resolution? - -Within a single thread, the execution order of objects is crucial for correct dependency resolution. -1. **Materials**: Material properties are typically computed first for an element. The `ComputeMaterialsObjectThread` is responsible for reinitializing and computing material properties for the current element, boundary, or neighbor element . This ensures that material properties are available to kernels that depend on them. -2. **Kernels**: After materials are reinitialized, `Kernel` objects are executed. The `NonlinearThread::computeOnElement()` method iterates through the active kernels for the current element . -3. **Dependency Resolution**: MOOSE's input file parsing and object registration system builds a dependency graph. Objects declare their dependencies (e.g., a kernel depends on a material property or another variable). The framework uses this information to ensure that objects are executed in the correct order. For example, `FEProblemBase::reinitScalars()` is called to reinitialize scalar variables, which might be dependencies for other computations . - -The `MooseObjectTagWarehouse` is used to manage and retrieve objects based on tags, which can influence their execution order . The `determineObjectWarehouses()` method in `NonlinearThread` is responsible for determining which objects will be computed based on vector/matrix tag information . - -## Relationships - -` ` `mermaid -graph TD - A[Executioner] --> B(FEProblemSolve) - B --> C[FEProblem] - C --> D[NonlinearSystemBase] - D --> E[ThreadedElementLoop] - E --> F[NonlinearThread] - F --> G[Assembly] - G --> H[Kernel] - G --> I[ADKernel] - - subgraph Threading - E -- "Splits element ranges" --> J[libMesh::n_threads()] - J -- "Each thread has" --> G - end - - subgraph Element Loop - F -- "1. reinit(elem)" --> C - F -- "2. computeOnElement()" --> H - F -- "2. computeOnElement()" --> I - H -- "3. accumulate _local_re/_local_ke" --> G - -Wiki pages you might want to explore: -- [Executioner and Time Integration (idaholab/moose)](https://deepwiki.com/idaholab/moose#3.2) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-cahn-hilliard-kernels.md b/packages/akms/src/akms/_bundled/global_nodes/moose-cahn-hilliard-kernels.md deleted file mode 100644 index 84b0dd9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-cahn-hilliard-kernels.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: moose-cahn-hilliard-kernels -title: MOOSE Cahn-Hilliard kernel implementation details -domain: phase-field -subdomain: algorithmic -tags: -- cahn-hilliard -- split-form -- SplitCHParsed -- SplitCHWRes -- biharmonic -- chemical-potential -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-allen-cahn-cahn-hilliard - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-allen-cahn-cahn-hilliard ---- - -# MOOSE Cahn-Hilliard kernel implementation details - -The MOOSE framework provides two primary implementations for the Cahn-Hilliard equation: a direct form and a split form. The direct form uses the `CahnHilliard` and `CHInterface` kernels to solve the fourth-order equation directly, while the split form decomposes the problem into two second-order equations solved by `SplitCHParsed` and `SplitCHWRes` kernels. The split form is generally preferred due to improved convergence properties and avoidance of C1 continuity requirements. - -## 1. Direct Form: `CahnHilliard` kernel — the biharmonic $\nabla^4 c$ problem — how handled? - -The direct form of the Cahn-Hilliard equation is solved using a combination of kernels, primarily `CahnHilliard` and `CHInterface` . The full weak form for the direct solution of the Cahn-Hilliard equation is given by: -$$ -\boldsymbol{\mathcal{R}}_{c_i} = \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( \kappa_i \nabla^2 c_i, \nabla \cdot (M_i \nabla \psi_m ) \right) + \left( M_i \left( \nabla \frac{\partial f_{loc} }{\partial c_i} + \nabla \frac{\partial E_d}{\partial c_i} \right), \nabla \psi_m \right) \quad (1) -$$ - -The `CahnHilliard` kernel implements the bulk free energy term : -$$ -\left(M \sum_j\nabla c_j\frac{\partial^2 f}{\partial c_i c_j}, \nabla \psi\right) -$$ -This corresponds to the term $\left( M_i \left( \nabla \frac{\partial f_{loc} }{\partial c_i} + \nabla \frac{\partial E_d}{\partial c_i} \right), \nabla \psi_m \right)$ in Equation (1) . - -The `CHInterface` kernel handles the gradient energy term : -$$ -\left( \kappa_i \nabla^2 c_i, \nabla \cdot (M_i \nabla \psi_m ) \right) -$$ -This term involves second-order derivatives of the concentration variable, which, when combined with the test function's derivatives, effectively addresses the biharmonic nature of the direct Cahn-Hilliard equation. - -## 2. Split Form: separate equations for $\mu$ and $c$ — `SplitCHParsed` + `SplitCHWRes` — what does each solve? - -The split form of the Cahn-Hilliard equation introduces an auxiliary variable, the chemical potential $\mu$, to break down the fourth-order equation into two coupled second-order equations . The two residual equations in weak form are: -$$ -\begin{aligned} - \boldsymbol{\mathcal{R}}_{\mu_i} &=& \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( M_i \nabla \mu_i, \nabla \psi_m \right) \\ - \boldsymbol{\mathcal{R}}_{c_i} &=& \left( \left( -\kappa_i \nabla^2 c_i + \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \mu_i \right), \psi_m \right) -\end{aligned} \quad (2) -$$ - -* **`SplitCHWRes`**: This kernel contributes to the residual equation for the chemical potential $\mu$ . Specifically, it implements the term $\left( M_i \nabla \mu_i, \nabla \psi_m \right)$ from the first equation in (2) . It takes the mobility `mob_name` as a parameter . -* **`SplitCHParsed`**: This kernel contributes to the residual equation for the concentration $c$ . It implements the term $\left( \left( -\kappa_i \nabla^2 c_i + \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \mu_i \right), \psi_m \right)$ from the second equation in (2) . It requires the free energy function name `f_name`, the gradient energy coefficient `kappa_name`, and the chemical potential variable `w` (which represents $\mu$) . - -## 3. Why is the split form preferred? Avoids C1 continuity requirements? - -The split form is preferred because it improves solve convergence . While the documentation doesn't explicitly state "avoids C1 continuity requirements," the decomposition of the fourth-order equation into two second-order equations inherently relaxes the continuity requirements for the finite element basis functions. Solving a fourth-order PDE directly typically requires C1 continuous basis functions (i.e., functions whose first derivatives are also continuous), which are more complex to implement and computationally more expensive than the C0 continuous basis functions (only the function itself is continuous) sufficient for second-order PDEs. - -## 4. The chemical potential variable $\mu$: how is it defined as $\mu = \partial f/\partial c$? - -In the split form, the chemical potential $\mu$ is implicitly defined through the second residual equation in (2) . The term $\left( \left( -\kappa_i \nabla^2 c_i + \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \mu_i \right), \psi_m \right)$ effectively enforces the relationship: -$$ -\mu_i = \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \kappa_i \nabla^2 c_i \quad (3) -$$ -This equation defines $\mu_i$ as the variational derivative of the total free energy with respect to $c_i$. The `SplitCHParsed` kernel uses the free energy function and its derivatives, typically provided by a `DerivativeParsedMaterial`, to compute the $\frac{\partial f_{loc}}{\partial c_i}$ and $\frac{\partial E_d}{\partial c_i}$ terms . - -## 5. `CHInterface` kernel for the gradient energy: $\int \kappa \cdot \nabla c \cdot \nabla \psi \, d\Omega$ - -The `CHInterface` kernel implements the interfacial or gradient energy term of the Cahn-Hilliard equation . In the direct form, this corresponds to the term $\left( \kappa_i \nabla^2 c_i, \nabla \cdot (M_i \nabla \psi_m ) \right)$ in Equation (1) . The `computeQpResidual` method in `CHInterfaceBase` shows the calculation of this residual term . - -## 6. Mobility in Cahn-Hilliard: `CoupledMaterialDerivative` or how $\nabla \cdot (M \nabla \mu)$ is discretized - -The mobility term $\nabla \cdot (M \nabla \mu)$ appears in the strong form of the Cahn-Hilliard equation. In the weak form for the split formulation, this term becomes $\left( M_i \nabla \mu_i, \nabla \psi_m \right)$ . This term is implemented by the `SplitCHWRes` kernel . The `computeQpResidual` method in `ADSplitCHWResBase` (an AD version of `SplitCHWResBase`) shows the calculation of this term as `_mob[_qp] * _grad_u[_qp]` , where `_grad_u` is the gradient of the variable the kernel is operating on (which is $\mu$ in this case) and `_mob` is the mobility material property. - -## 7. Variable mobility: $M(c)$ — how its derivative enters the Jacobian - -When the mobility $M$ is a function of concentration $c$, i.e., $M(c)$, its derivative with respect to $c$ enters the Jacobian. In the `CHInterfaceBase` kernel, which is used in the direct formulation, the `computeQpJacobian` method explicitly includes terms involving derivatives of the mobility, such as `_dMdc` and `_d2Mdc2` . These represent $\frac{\partial M}{\partial c}$ and $\frac{\partial^2 M}{\partial c^2}$ respectively. Similarly, for coupled variables, `_dMdarg` and `_d2Mdcdarg` are used . - -In the split form, for the `SplitCHWResBase` kernel, if the mobility `_mob` depends on coupled variables, its derivatives `_dmobdarg` are used in `computeQpOffDiagJacobian` to calculate the off-diagonal Jacobian entries . - -## Classes & Methods - -* `CahnHilliard::CahnHilliard()`: Implements the bulk free energy term for the direct Cahn-Hilliard formulation. -* `CHInterface::CHInterface()`: Implements the gradient energy term for the direct Cahn-Hilliard formulation. -* `SplitCHParsed::SplitCHParsed()`: Implements the concentration residual equation in the split Cahn-Hilliard formulation, including free energy and gradient terms. -* `SplitCHWRes::SplitCHWRes()`: Implements the chemical potential residual equation in the split Cahn-Hilliard formulation, including the mobility term. -* `CHInterfaceBase::computeQpResidual()`: Calculates the residual for the gradient energy term in the direct Cahn-Hilliard equation. -* `CHInterfaceBase::computeQpJacobian()`: Calculates the Jacobian for the gradient energy term, including mobility derivatives. -* `ADSplitCHWResBase::precomputeQpResidual()`: Calculates the residual for the chemical potential equation in the split Cahn-Hilliard formulation. -* `SplitCHWResBase::computeQpOffDiagJacobian()`: Calculates off-diagonal Jacobian entries for the chemical potential equation, considering mobility derivatives. -* `SplitCHCRes::computeQpResidual()`: Calculates the residual for the concentration equation in the split Cahn-Hilliard formulation. -* `SplitCHCRes::computeQpJacobian()`: Calculates the Jacobian for the concentration equation. -* `SplitCHCRes::computeQpOffDiagJacobian()`: Calculates off-diagonal Jacobian entries for the concentration equation. - -## Equations - -**Direct Cahn-Hilliard Weak Form:** -$$ -\boldsymbol{\mathcal{R}}_{c_i} = \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( \kappa_i \nabla^2 c_i, \nabla \cdot ( - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-cdm.md b/packages/akms/src/akms/_bundled/global_nodes/moose-cdm.md deleted file mode 100644 index 43ea0cb..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-cdm.md +++ /dev/null @@ -1,301 +0,0 @@ ---- -id: moose-cdm -title: MOOSE Continuum damage mechanics in MOOSE -domain: constitutive -subdomain: algorithmic -tags: -- damage -- CDM -- scalar-damage -- stress-degradation -- nonlocal-regularization -- crack-band -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-continuum-damage - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-continuum-damage -- to: cm-gtn-ductile-fracture - type: implements - weight: 0.7 - note: Continuum damage mechanics framework ---- - -# MOOSE Continuum damage mechanics in MOOSE - -MOOSE implements continuum damage mechanics (CDM) through a system of material models that define and apply a scalar damage variable to degrade stress and stiffness. The core components involve a base class for damage models, concrete implementations for damage evolution, and a specialized stress calculator that integrates the damage effect. Nonlocal damage regularization is also available. - -## Classes & Methods: - -* `DamageBaseTempl`: An abstract base class for damage models, defining the interface for updating damage, stress, and Jacobian multipliers. -* `DamageBaseTempl::updateDamage()`: A virtual method in `DamageBaseTempl` that derived classes override to implement their specific damage evolution laws. -* `DamageBaseTempl::updateStressForDamage(GenericRankTwoTensor & stress_new)`: A pure virtual method in `DamageBaseTempl` responsible for modifying the stress tensor based on the calculated damage. -* `DamageBaseTempl::updateJacobianMultForDamage(RankFourTensor & jacobian_mult)`: A pure virtual method in `DamageBaseTempl` for updating the material constitutive matrix due to damage. -* `ScalarDamageBaseTempl`: A base class for scalar damage models, inheriting from `DamageBaseTempl`. It manages the scalar damage index and provides methods for its update. -* `ScalarDamageBaseTempl::updateQpDamageIndex()`: A pure virtual method in `ScalarDamageBaseTempl` that concrete scalar damage models must implement to compute the damage index at each quadrature point. -* `ScalarMaterialDamageTempl`: A concrete implementation of `ScalarDamageBaseTempl` where the damage index is prescribed by another material property. -* `CombinedScalarDamageTempl`: A scalar damage model that combines multiple damage models using either a "Maximum" or "Product" rule. -* `NonlocalDamageTempl`: Implements nonlocal damage regularization by averaging a local damage property over a characteristic length. -* `ComputeDamageStressTempl`: A material model that computes stress for damaged elastic materials by interacting with a `DamageBase` derived model. -* `ComputeDamageStressTempl::computeQpStress()`: Overrides the base class method to apply damage to the computed stress and Jacobian. - -## Equations: - -1. **Stress Degradation**: The stress $\boldsymbol{\sigma}$ is degraded by the scalar damage variable $d$ from the undamaged stress $\boldsymbol{\sigma}_0$ (or stiffness $\mathbb{C}$ and elastic strain $\boldsymbol{\varepsilon}$). - $$ \boldsymbol{\sigma} = (1 - d)\ \mathbb{C} : \boldsymbol{\varepsilon} $$ - This is implemented in `DamageBaseTempl::updateStressForDamage` and `DamageBaseTempl::updateJacobianMultForDamage`. - -2. **Combined Damage Evolution**: When multiple damage models are used, the total damage $d$ can be computed as either the maximum of individual damage variables ($d_i$) or a product combination. - $$ \mathrm{Maximum:} \quad d = \mathrm{max}(d_1 ... d_N) $$ - $$ \mathrm{Product:} \quad d = 1 - \prod_{i=1}^{N} (1 - d_i) $$ - This is handled by the `CombinedScalarDamage` class. - -## Algorithm Steps: - -The interaction between damage models and stress computation follows these steps: - -1. An elastic stress is computed by a class like `ComputeFiniteStrainElasticStressTempl`. -2. `ComputeDamageStressTempl` retrieves the associated damage model. -3. The damage model's `updateDamage()` method is called to evolve the damage variable. -4. The `updateStressForDamage()` method of the damage model modifies the computed stress. -5. The `updateJacobianMultForDamage()` method of the damage model modifies the material constitutive matrix. - -` ` `pseudocode -function computeQpStress() - ComputeFiniteStrainElasticStress() // Compute undamaged stress - _damage_model.setQp(_qp) - _damage_model.updateDamage() // Evolve damage variable - _damage_model.updateStressForDamage(this->_stress[_qp]) // Degrade stress - _damage_model.finiteStrainRotation(this->_rotation_increment[_qp]) - _damage_model.updateJacobianMultForDamage(_Jacobian_mult[_qp]) // Degrade Jacobian - _material_timestep_limit[_qp] = _damage_model.computeTimeStepLimit() -end function -` ` ` - - -## Parameters: - -* `damage_model`: (Required, MaterialName) Name of the damage model to be used with `ComputeDamageStress`. -* `damage_index`: (Required, MaterialPropertyName) Name of the material property containing the damage index for `ScalarMaterialDamage`. -* `damage_models`: (Vector of MaterialName) List of damage models to combine in `CombinedScalarDamage`. -* `combination_type`: (Enum: Maximum, Product) Specifies how multiple damage models are combined in `CombinedScalarDamage`. Default is `Maximum`. -* `local_damage_model`: (MaterialName) The local damage model used by `NonlocalDamage` for averaging. -* `average_UO`: (UserObject) The `RadialAverage` UserObject used by `NonlocalDamage` for nonlocal regularization. - -## Relationships: - -` ` `mermaid -classDiagram - class Material { - +InputParameters validParams() - } - class DamageBaseTempl { - <> - +void updateDamage() - +void updateStressForDamage(GenericRankTwoTensor& stress_new) - +void updateJacobianMultForDamage(RankFourTensor& jacobian_mult) - +Real computeTimeStepLimit() - } - class ScalarDamageBaseTempl { - <> - +void updateQpDamageIndex() - -GenericMaterialProperty& _damage_index - } - class ScalarMaterialDamageTempl { - -const GenericMaterialProperty& _damage_property - } - class CombinedScalarDamageTempl { - -CombinationType _combination_type - -std::vector _damage_models - } - class NonlocalDamageTempl { - -const RadialAverage::Result& _average - -ScalarDamageBaseTempl* _local_damage_model - } - class ComputeFiniteStrainElasticStressTempl { - +void computeQpStress() - } - class ComputeDamageStressTempl { - -DamageBaseTempl* _damage_model - +void computeQpStress() - } - - Material <|-- DamageBaseTempl - DamageBaseTempl <|-- ScalarDamageBaseTempl - ScalarDamageBaseTempl <|-- ScalarMaterialDamageTempl - ScalarDamageBaseTempl <|-- CombinedScalarDamageTempl - ScalarDamageBaseTempl <|-- NonlocalDamageTempl - ComputeFiniteStrainElasticStressTempl <|-- ComputeDamageStressTempl - - ComputeDamageStressTempl "1" *-- "1" DamageBaseTempl : uses > - CombinedScalarDamageTempl "1" *-- "N" ScalarDamageBaseTempl : combines > - NonlocalDamageTempl "1" *-- "1" ScalarDamageBaseTempl : uses local damage model > -` ` ` - -## Code Snippets: - -**`DamageBase.h` - Abstract Base Class for Damage Models** -` ` `cpp -template -class DamageBaseTempl : public Material -{ -public: - static InputParameters validParams(); - - DamageBaseTempl(const InputParameters & parameters); - - /** - * Update the internal variable(s) that evolve the damage - */ - virtual void updateDamage(); - - /** - * Update the current stress tensor for effects of damage. - * @param stress_new Undamaged stress to be modified by the damage model - */ - virtual void updateStressForDamage(GenericRankTwoTensor & stress_new) = 0; - - /** - * Update the material constitutive matrix - * @param jacobian_mult Material constitutive matrix to be modified for - * effects of damage - */ - virtual void updateJacobianMultForDamage(RankFourTensor & jacobian_mult) = 0; -` ` ` - - -**`ScalarDamageBase.h` - Base Class for Scalar Damage Models** -` ` `cpp -template -class ScalarDamageBaseTempl : public DamageBaseTempl -{ -public: - static InputParameters validParams(); - - ScalarDamageBaseTempl(const InputParameters & parameters); - - virtual void initQpStatefulProperties() override; - - virtual void updateDamage() override; - - virtual void updateStressForDamage(GenericRankTwoTensor & stress_new) override; - - virtual void updateJacobianMultForDamage(RankFourTensor & jacobian_mult) override; - - virtual void computeUndamagedOldStress(RankTwoTensor & stress_old) override; - - virtual Real computeTimeStepLimit() override; - - /** - * Get the value of the damage index for the current quadrature point. - */ - const GenericReal & getQpDamageIndex(unsigned int qp); - - /** - * Get the name of the material property containing the damage index - */ - const std::string getDamageIndexName() const { return _damage_index_name; } - -protected: - /// Name of the material property where the damage index is stored - const MaterialPropertyName _damage_index_name; - - /// Update the damage index at the current qpoint - virtual void updateQpDamageIndex() = 0; -` ` ` - - -**`ComputeDamageStress.C` - Stress Computation with Damage** -` ` `cpp -template <> -void -ComputeDamageStressTempl::computeQpStress() -{ - ComputeFiniteStrainElasticStressTempl::computeQpStress(); - - _damage_model->setQp(_qp); - _damage_model->updateDamage(); - _damage_model->updateStressForDamage(this->_stress[_qp]); - _damage_model->finiteStrainRotation(this->_rotation_increment[_qp]); - _damage_model->updateJacobianMultForDamage(_Jacobian_mult[_qp]); - - _material_timestep_limit[_qp] = _damage_model->computeTimeStepLimit(); -} -` ` ` - - -## MOOSE Input Syntax: - -**Basic Scalar Damage Model** -` ` `ini -[Materials] - [damage_index] - type = GenericFunctionMaterial - prop_names = damage_index_prop - prop_values = damage_evolution - [] - [damage] - type = ScalarMaterialDamage - damage_index = damage_index_prop - [] - [stress] - type = ComputeDamageStress - damage_model = damage - [] - [elasticity] - type = ComputeIsotropicElasticityTensor - poissons_ratio = 0.2 - youngs_modulus = 10e9 - [] -[] -` ` ` - - -**Combined Scalar Damage Model** -` ` `ini -[Materials] - [damage_index_a] - type = GenericFunctionMaterial - prop_names = damage_index_prop_a - prop_values = damage_evolution_a - [] - [damage_index_b] - type = GenericFunctionMaterial - prop_names = damage_index_prop_b - prop_values = damage_evolution_b - [] - [damage_a] - type = ScalarMaterialDamage - damage_index = damage_index_prop_a - damage_index_name = damage_index_a - [] - [damage_b] - type = ScalarMaterialDamage - damage_index = damage_index_prop_b - damage_index_name = damage_index_b - [] - [damage] - type = CombinedScalarDamage - damage_models = 'damage_a damage_b' - [] - [stress] - type = ComputeDamageStress - damage_model = damage - [] - [elasticity] - type = ComputeIsotropicElasticityTensor - poissons_ratio = 0.2 - youngs_modulus = 10e9 - [] -[] -` ` ` -< - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-continuum-damage.md b/packages/akms/src/akms/_bundled/global_nodes/moose-continuum-damage.md deleted file mode 100644 index 2e57fd2..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-continuum-damage.md +++ /dev/null @@ -1,308 +0,0 @@ ---- -id: moose-continuum-damage -title: MOOSE Damage and Fracture Mechanics (Non-Phase-Field) -domain: constitutive -subdomain: algorithmic -tags: -- damage -- CDM -- scalar-damage -- stress-degradation -- nonlocal-regularization -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-stress-computation-chain - type: requires - weight: 0.7 - note: Part of the stress computation dispatch chain -- to: moose-return-mapping-base - type: requires - weight: 0.6 - note: Damage models can use return mapping framework -- to: cm-gtn-ductile-fracture - type: implements - weight: 0.7 - note: Implements continuum damage mechanics framework ---- - -# MOOSE Damage and Fracture Mechanics (Non-Phase-Field) - -Framework knowledge node covering 1 aspect(s) of Damage and Fracture Mechanics (Non-Phase-Field). - -## Continuum damage mechanics in MOOSE - -MOOSE implements continuum damage mechanics (CDM) through a system of material models that define and apply a scalar damage variable to degrade stress and stiffness. The core components involve a base class for damage models, concrete implementations for damage evolution, and a specialized stress calculator that integrates the damage effect. Nonlocal damage regularization is also available. - -## Classes & Methods: - -* `DamageBaseTempl`: An abstract base class for damage models, defining the interface for updating damage, stress, and Jacobian multipliers. -* `DamageBaseTempl::updateDamage()`: A virtual method in `DamageBaseTempl` that derived classes override to implement their specific damage evolution laws. -* `DamageBaseTempl::updateStressForDamage(GenericRankTwoTensor & stress_new)`: A pure virtual method in `DamageBaseTempl` responsible for modifying the stress tensor based on the calculated damage. -* `DamageBaseTempl::updateJacobianMultForDamage(RankFourTensor & jacobian_mult)`: A pure virtual method in `DamageBaseTempl` for updating the material constitutive matrix due to damage. -* `ScalarDamageBaseTempl`: A base class for scalar damage models, inheriting from `DamageBaseTempl`. It manages the scalar damage index and provides methods for its update. -* `ScalarDamageBaseTempl::updateQpDamageIndex()`: A pure virtual method in `ScalarDamageBaseTempl` that concrete scalar damage models must implement to compute the damage index at each quadrature point. -* `ScalarMaterialDamageTempl`: A concrete implementation of `ScalarDamageBaseTempl` where the damage index is prescribed by another material property. -* `CombinedScalarDamageTempl`: A scalar damage model that combines multiple damage models using either a "Maximum" or "Product" rule. -* `NonlocalDamageTempl`: Implements nonlocal damage regularization by averaging a local damage property over a characteristic length. -* `ComputeDamageStressTempl`: A material model that computes stress for damaged elastic materials by interacting with a `DamageBase` derived model. -* `ComputeDamageStressTempl::computeQpStress()`: Overrides the base class method to apply damage to the computed stress and Jacobian. - -## Equations: - -1. **Stress Degradation**: The stress $\boldsymbol{\sigma}$ is degraded by the scalar damage variable $d$ from the undamaged stress $\boldsymbol{\sigma}_0$ (or stiffness $\mathbb{C}$ and elastic strain $\boldsymbol{\varepsilon}$). - $$ \boldsymbol{\sigma} = (1 - d)\ \mathbb{C} : \boldsymbol{\varepsilon} $$ - This is implemented in `DamageBaseTempl::updateStressForDamage` and `DamageBaseTempl::updateJacobianMultForDamage`. - -2. **Combined Damage Evolution**: When multiple damage models are used, the total damage $d$ can be computed as either the maximum of individual damage variables ($d_i$) or a product combination. - $$ \mathrm{Maximum:} \quad d = \mathrm{max}(d_1 ... d_N) $$ - $$ \mathrm{Product:} \quad d = 1 - \prod_{i=1}^{N} (1 - d_i) $$ - This is handled by the `CombinedScalarDamage` class. - -## Algorithm Steps: - -The interaction between damage models and stress computation follows these steps: - -1. An elastic stress is computed by a class like `ComputeFiniteStrainElasticStressTempl`. -2. `ComputeDamageStressTempl` retrieves the associated damage model. -3. The damage model's `updateDamage()` method is called to evolve the damage variable. -4. The `updateStressForDamage()` method of the damage model modifies the computed stress. -5. The `updateJacobianMultForDamage()` method of the damage model modifies the material constitutive matrix. - -` ` `pseudocode -function computeQpStress() - ComputeFiniteStrainElasticStress() // Compute undamaged stress - _damage_model.setQp(_qp) - _damage_model.updateDamage() // Evolve damage variable - _damage_model.updateStressForDamage(this->_stress[_qp]) // Degrade stress - _damage_model.finiteStrainRotation(this->_rotation_increment[_qp]) - _damage_model.updateJacobianMultForDamage(_Jacobian_mult[_qp]) // Degrade Jacobian - _material_timestep_limit[_qp] = _damage_model.computeTimeStepLimit() -end function -` ` ` - - -## Parameters: - -* `damage_model`: (Required, MaterialName) Name of the damage model to be used with `ComputeDamageStress`. -* `damage_index`: (Required, MaterialPropertyName) Name of the material property containing the damage index for `ScalarMaterialDamage`. -* `damage_models`: (Vector of MaterialName) List of damage models to combine in `CombinedScalarDamage`. -* `combination_type`: (Enum: Maximum, Product) Specifies how multiple damage models are combined in `CombinedScalarDamage`. Default is `Maximum`. -* `local_damage_model`: (MaterialName) The local damage model used by `NonlocalDamage` for averaging. -* `average_UO`: (UserObject) The `RadialAverage` UserObject used by `NonlocalDamage` for nonlocal regularization. - -## Relationships: - -` ` `mermaid -classDiagram - class Material { - +InputParameters validParams() - } - class DamageBaseTempl { - <> - +void updateDamage() - +void updateStressForDamage(GenericRankTwoTensor& stress_new) - +void updateJacobianMultForDamage(RankFourTensor& jacobian_mult) - +Real computeTimeStepLimit() - } - class ScalarDamageBaseTempl { - <> - +void updateQpDamageIndex() - -GenericMaterialProperty& _damage_index - } - class ScalarMaterialDamageTempl { - -const GenericMaterialProperty& _damage_property - } - class CombinedScalarDamageTempl { - -CombinationType _combination_type - -std::vector _damage_models - } - class NonlocalDamageTempl { - -const RadialAverage::Result& _average - -ScalarDamageBaseTempl* _local_damage_model - } - class ComputeFiniteStrainElasticStressTempl { - +void computeQpStress() - } - class ComputeDamageStressTempl { - -DamageBaseTempl* _damage_model - +void computeQpStress() - } - - Material <|-- DamageBaseTempl - DamageBaseTempl <|-- ScalarDamageBaseTempl - ScalarDamageBaseTempl <|-- ScalarMaterialDamageTempl - ScalarDamageBaseTempl <|-- CombinedScalarDamageTempl - ScalarDamageBaseTempl <|-- NonlocalDamageTempl - ComputeFiniteStrainElasticStressTempl <|-- ComputeDamageStressTempl - - ComputeDamageStressTempl "1" *-- "1" DamageBaseTempl : uses > - CombinedScalarDamageTempl "1" *-- "N" ScalarDamageBaseTempl : combines > - NonlocalDamageTempl "1" *-- "1" ScalarDamageBaseTempl : uses local damage model > -` ` ` - -## Code Snippets: - -**`DamageBase.h` - Abstract Base Class for Damage Models** -` ` `cpp -template -class DamageBaseTempl : public Material -{ -public: - static InputParameters validParams(); - - DamageBaseTempl(const InputParameters & parameters); - - /** - * Update the internal variable(s) that evolve the damage - */ - virtual void updateDamage(); - - /** - * Update the current stress tensor for effects of damage. - * @param stress_new Undamaged stress to be modified by the damage model - */ - virtual void updateStressForDamage(GenericRankTwoTensor & stress_new) = 0; - - /** - * Update the material constitutive matrix - * @param jacobian_mult Material constitutive matrix to be modified for - * effects of damage - */ - virtual void updateJacobianMultForDamage(RankFourTensor & jacobian_mult) = 0; -` ` ` - - -**`ScalarDamageBase.h` - Base Class for Scalar Damage Models** -` ` `cpp -template -class ScalarDamageBaseTempl : public DamageBaseTempl -{ -public: - static InputParameters validParams(); - - ScalarDamageBaseTempl(const InputParameters & parameters); - - virtual void initQpStatefulProperties() override; - - virtual void updateDamage() override; - - virtual void updateStressForDamage(GenericRankTwoTensor & stress_new) override; - - virtual void updateJacobianMultForDamage(RankFourTensor & jacobian_mult) override; - - virtual void computeUndamagedOldStress(RankTwoTensor & stress_old) override; - - virtual Real computeTimeStepLimit() override; - - /** - * Get the value of the damage index for the current quadrature point. - */ - const GenericReal & getQpDamageIndex(unsigned int qp); - - /** - * Get the name of the material property containing the damage index - */ - const std::string getDamageIndexName() const { return _damage_index_name; } - -protected: - /// Name of the material property where the damage index is stored - const MaterialPropertyName _damage_index_name; - - /// Update the damage index at the current qpoint - virtual void updateQpDamageIndex() = 0; -` ` ` - - -**`ComputeDamageStress.C` - Stress Computation with Damage** -` ` `cpp -template <> -void -ComputeDamageStressTempl::computeQpStress() -{ - ComputeFiniteStrainElasticStressTempl::computeQpStress(); - - _damage_model->setQp(_qp); - _damage_model->updateDamage(); - _damage_model->updateStressForDamage(this->_stress[_qp]); - _damage_model->finiteStrainRotation(this->_rotation_increment[_qp]); - _damage_model->updateJacobianMultForDamage(_Jacobian_mult[_qp]); - - _material_timestep_limit[_qp] = _damage_model->computeTimeStepLimit(); -} -` ` ` - - -## MOOSE Input Syntax: - -**Basic Scalar Damage Model** -` ` `ini -[Materials] - [damage_index] - type = GenericFunctionMaterial - prop_names = damage_index_prop - prop_values = damage_evolution - [] - [damage] - type = ScalarMaterialDamage - damage_index = damage_index_prop - [] - [stress] - type = ComputeDamageStress - damage_model = damage - [] - [elasticity] - type = ComputeIsotropicElasticityTensor - poissons_ratio = 0.2 - youngs_modulus = 10e9 - [] -[] -` ` ` - - -**Combined Scalar Damage Model** -` ` `ini -[Materials] - [damage_index_a] - type = GenericFunctionMaterial - prop_names = damage_index_prop_a - prop_values = damage_evolution_a - [] - [damage_index_b] - type = GenericFunctionMaterial - prop_names = damage_index_prop_b - prop_values = damage_evolution_b - [] - [damage_a] - type = ScalarMaterialDamage - damage_index = damage_index_prop_a - damage_index_name = damage_index_a - [] - [damage_b] - type = ScalarMaterialDamage - damage_index = damage_index_prop_b - damage_index_name = damage_index_b - [] - [damage] - type = CombinedScalarDamage - damage_models = 'damage_a damage_b' - [] - [stress] - type = ComputeDamageStress - damage_model = damage - [] - [elasticity] - type = ComputeIsotropicElasticityTensor - poissons_ratio = 0.2 - youngs_modulus = 10e9 - [] -[] -` ` ` -< - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-hardening.md b/packages/akms/src/akms/_bundled/global_nodes/moose-cp-hardening.md deleted file mode 100644 index adbb529..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-hardening.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -id: moose-cp-hardening -title: MOOSE Crystal plasticity hardening laws -domain: constitutive -subdomain: algorithmic -tags: -- hardening -- taylor -- voce -- kocks-mecking -- latent-hardening -- slip-resistance -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-crystal-plasticity - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-crystal-plasticity ---- - -# MOOSE Crystal plasticity hardening laws - -The MOOSE framework implements several hardening laws for crystal plasticity, primarily through the `CrystalPlasticityKalidindiUpdate` class and the `CrystalPlasticityStateVarRateComponentVoce` UserObject . These implementations handle self and latent hardening, and store history variables like slip resistance as material properties . - -## Hardening Laws Implemented - -### Kalidindi Hardening Model -The `CrystalPlasticityKalidindiUpdate` class implements the self and latent hardening crystal plasticity model developed by Kalidindi et al. (1992) . - -**Equations:** -The slip rate is given by a power law relationship: -$$ -\dot{\gamma}^{\alpha} = \dot{\gamma}_o \left| \frac{\tau^{\alpha}}{g^{\alpha}} \right|^{1/m} sign \left( \tau^{\alpha} \right) \quad (1) -$$ -where $\dot{\gamma}_o$ is a reference slip rate, $\tau^{\alpha}$ is the applied shear stress, $g^{\alpha}$ is the slip system strength (resistance to slip), and $m$ is the strain rate sensitivity exponent . - -The evolution of slip system strength (resistance) is given by: -$$ -g^{\alpha} = g_o + \Delta \gamma^{\alpha} q^{\alpha \beta} h_o \left| 1 - \frac{g^{\alpha}}{g_{sat}} \right|^a sign \left( 1 - \frac{g^{\alpha}}{g_{sat}} \right) \quad (2) -$$ -where $q^{\alpha \beta}$ is the hardening coefficient matrix, $h_o$ is an initial hardening term, $g_{sat}$ is the saturated hardening value, and $a$ is the hardening exponent . - -The hardening coefficient matrix $q^{\alpha \beta}$ for an FCC system is defined as: -$$ -q^{\alpha \beta} = \begin{Bmatrix} - 1.0 & q & q & q \\ - q & 1.0 & q & q \\ - q & q & 1.0 & q \\ - q & q & q & 1.0 - \end{Bmatrix} \quad (3) -$$ -where $q$ is a constant value of latent hardening among non-coplanar slip systems . - -**Classes & Methods:** -* `CrystalPlasticityKalidindiUpdate::validParams()`: Defines the input parameters for the Kalidindi hardening model . -* `CrystalPlasticityKalidindiUpdate::initQpStatefulProperties()`: Initializes stateful properties like slip system resistances . -* `CrystalPlasticityKalidindiUpdate::setInitialConstitutiveVariableValues()`: Sets initial values for constitutive variables . -* `CrystalPlasticityKalidindiUpdate::calculateSlipRate()`: Calculates the slip rate for each slip system . -* `CrystalPlasticityKalidindiUpdate::calculateStateVariableEvolutionRateComponent()`: Calculates the slip system resistance increment based on Kalidindi et al. (1992) . -* `CrystalPlasticityKalidindiUpdate::updateStateVariables()`: Finalizes the values of state variables after convergence . - -**Parameters:** -The `CrystalPlasticityKalidindiUpdate` class uses the following parameters : -* `r`: Latent hardening coefficient (default: 1.0) -* `h`: Hardening constant (default: 541.5) -* `t_sat`: Saturated slip system strength (default: 109.8) -* `gss_a`: Coefficient for hardening (default: 2.5) -* `ao`: Slip rate coefficient (default: 0.001) -* `xm`: Exponent for slip rate (default: 0.1) -* `gss_initial`: Initial lattice friction strength (default: 60.8) -* `total_twin_volume_fraction`: Name of the material property for total twin volume fraction, if twinning is considered . - -### Voce Hardening Model -The `CrystalPlasticityStateVarRateComponentVoce` UserObject implements a phenomenological Voce constitutive model for state variable evolution . - -**Equations:** -The hardening rate `hb(i)` for a slip system `i` is calculated as: -$$ -hb(i) = h_0 \left| 1 - \frac{g^{\alpha} - \tau_0}{\tau_{sat} - \tau_0} \right|^{hardening\_exponent} \text{sign}\left(1 - \frac{g^{\alpha} - \tau_0}{\tau_{sat} - \tau_0}\right) \quad (4) -$$ -where $h_0$ is an initial hardening constant, $\tau_0$ is the initial critical resolved shear stress, $\tau_{sat}$ is the saturation resolved shear stress, and $hardening\_exponent$ is the hardening exponent . -The evolution rate of the state variable `val[i]` is then calculated by summing contributions from all slip systems `j`, considering self and latent hardening coefficients `q_ab`: -$$ -val[i] += |\dot{\gamma}_{j}| \cdot q_{ab} \cdot hb(j) \quad (5) -$$ - -**Classes & Methods:** -* `CrystalPlasticityStateVarRateComponentVoce::validParams()`: Defines input parameters for the Voce hardening model . -* `CrystalPlasticityStateVarRateComponentVoce::calcStateVariableEvolutionRateComponent()`: Computes the slip system hardening rate . -* `CrystalPlasticityStateVarRateComponentVoce::getHardeningCoefficient()`: Retrieves the appropriate self/latent hardening coefficient . - -**Parameters:** -The `CrystalPlasticityStateVarRateComponentVoce` class uses the following parameters : -* `uo_slip_rate_name`: Name of the slip rate property. -* `uo_state_var_name`: Name of the state variable property. -* `crystal_lattice_type`: Type of crystal lattice structure (e.g., "FCC", "BCC"). -* `groups`: Defines slip system groups (e.g., '0 12 24 48'). -* `h0_group_values`: `h0` hardening constant for each group. -* `tau0_group_values`: Initial critical resolved shear stress for each group. -* `tauSat_group_values`: Saturation resolved shear stress for each group. -* `hardeningExponent_group_values`: Hardening exponent for each group. -* `selfHardening_group_values`: Self-hardening coefficient `q_aa` for each group. -* `coplanarHardening_group_values`: Coplanar latent hardening coefficient `q_ab` for each group. -* `GroupGroup_Hardening_group_values`: Group-to-group latent hardening coefficient `q_ab` (N x N matrix). - -**MOOSE Input Syntax Example:** -` ` `ini -[UserObjects] - [./state_var_evol_rate_comp_voce] - type = CrystalPlasticityStateVarRateComponentVoce - variable_size = 48 - crystal_lattice_type = 'BCC' - groups = '0 12 24 48' - h0_group_values = '1 2 3' - tau0_group_values = '50 51 52' - tauSat_group_values = '70 81 92' - hardeningExponent_group_values = '1 2 3' - selfHardening_group_values ='4 5 6' - coplanarHardening_group_values='7 8 9' - GroupGroup_Hardening_group_values = '10 20 30 - 40 50 60 - 70 80 90' - uo_slip_rate_name = slip_rate_gss - uo_state_var_name = state_var_gss - [../] -[] -` ` ` - -### Beyerlein Hardening Model (HCP) -The `CrystalPlasticityHCPDislocationSlipBeyerleinUpdate` class implements a constitutive model for the glide and evolution of forest dislocations within an HCP crystal lattice . This model considers contributions from initial lattice friction, Hall-Petch type hardening, forest dislocations, and substructure density . - -**Equations:** -The total slip resistance $g^{\alpha}$ is the sum of four terms: -$$ -g^{\alpha} = g^{\alpha}_o + g^{\alpha}_{HP} + g^{\alpha}_{forest} + g^{\alpha}_{sub} \quad (6) -$$ -where $g^{\alpha}_o$ is initial lattice friction, $g^{\alpha}_{HP}$ is Hall-Petch hardening, $g^{\alpha}_{forest}$ is forest dislocation hardening, and $g^{\alpha}_{sub}$ is substructure hardening . - -Hall-Petch hardening: -$$ -g^{\alpha}_{HP} = HP^{\alpha}\mu^{\alpha} \sqrt{\frac{b^{\alpha}}{d_g}} \quad (7) -$$ - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-orientation.md b/packages/akms/src/akms/_bundled/global_nodes/moose-cp-orientation.md deleted file mode 100644 index 815ca55..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-orientation.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -id: moose-cp-orientation -title: MOOSE Crystal plasticity slip systems and orientation -domain: constitutive -subdomain: algorithmic -tags: -- slip-systems -- euler-angles -- bunge-convention -- EBSD -- grain-tracker -- texture -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-crystal-plasticity - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-crystal-plasticity ---- - -# MOOSE Crystal plasticity slip systems and orientation - -MOOSE handles crystallographic orientations and slip systems primarily within the `solid_mechanics` module, particularly for crystal plasticity models . It supports defining slip systems from files, reading Euler angles (Bunge convention), applying crystal-to-sample rotations, and integrating with EBSD data for polycrystal orientations . - -## Slip System Definition Files - -Slip systems are defined in external text files, which are then read by MOOSE . The `CrystalPlasticityStressUpdateBase` class handles reading these files . - -### Format for Specifying {hkl} Systems - -The slip system files typically contain the slip plane normal and slip direction vectors . For HCP crystals, a 4-index Miller-Bravais notation can be transformed into a 3-index Cartesian representation . - -**Parameters:** -* `slip_sys_file_name` = "path/to/file.txt" (type: `FileName`, required): Name of the file containing slip systems, with the slip plane normal given before the slip plane direction . -* `number_slip_systems` (type: `unsigned int`, required): The total number of possible active slip systems . -* `crystal_lattice_type` (type: `MooseEnum`, default: "FCC"): Specifies the crystal lattice type (BCC, FCC, HCP) . -* `unit_cell_dimension` (type: `std::vector`, default: `{1.0, 1.0, 1.0}`): Dimensions of the unit cell, used for computing slip systems . - -**Code Snippets:** -The `getSlipSystems()` method in `CrystalPlasticityStressUpdateBase` reads and normalizes the slip system vectors . For HCP crystals, `transformHexagonalMillerBravaisSlipSystems()` performs the coordinate transformation . - -` ` `cpp -void -CrystalPlasticityStressUpdateBase::getSlipSystems() -{ - bool orthonormal_error = false; - - // read in the slip system data from auxiliary text file - MooseUtils::DelimitedFileReader _reader(_slip_sys_file_name); - _reader.setFormatFlag(MooseUtils::DelimitedFileReader::FormatFlag::ROWS); - _reader.read(); - - // check the size of the input - if (_reader.getData().size() != _number_slip_systems) - paramError( - "number_slip_systems", - "The number of rows in the slip system file should match the number of slip system."); - - for (const auto i : make_range(_number_slip_systems)) - { - // initialize to zero - _slip_direction[i].zero(); - _slip_plane_normal[i].zero(); - } - - if (_crystal_lattice_type == CrystalLatticeType::HCP) - transformHexagonalMillerBravaisSlipSystems(_reader); - else if (_crystal_lattice_type == CrystalLatticeType::BCC || - _crystal_lattice_type == CrystalLatticeType::FCC) - { - for (const auto i : make_range(_number_slip_systems)) - { - // directly grab the raw data and scale it by the unit cell dimension - for (const auto j : index_range(_reader.getData(i))) - { - if (j < LIBMESH_DIM) - _slip_plane_normal[i](j) = _reader.getData(i)[j] / _unit_cell_dimension[j]; - else - _slip_direction[i](j - LIBMESH_DIM) = - _reader.getData(i)[j] * _unit_cell_dimension[j - LIBMESH_DIM]; - } - } - } - - for (const auto i : make_range(_number_slip_systems)) - { - // normalize - _slip_plane_normal[i] /= _slip_plane_normal[i].norm(); - _slip_direction[i] /= _slip_direction[i].norm(); - - if (_crystal_lattice_type != CrystalLatticeType::HCP) - { - const auto magnitude = _slip_plane_normal[i] * _slip_direction[i]; - if (std::abs(magnitude) > libMesh::TOLERANCE) - { - orthonormal_error = true; - break; - } - } - } - - if (orthonormal_error) - mooseError("CrystalPlasticityStressUpdateBase Error: The slip system file contains a slip " - "direction and plane normal pair that are not orthonormal in the Cartesian " - "coordinate system."); -} -` ` ` - -## Euler Angle Input and Rotation Tensors - -MOOSE uses Euler angles to define crystallographic orientations, primarily following the Bunge convention . - -### Euler Angle Input: Bunge Convention - -The `ComputeElasticityTensorCP` class accepts Bunge Euler angles as input . These can be provided directly in the input file, read from a `PropertyReadFile` user object, or coupled from other variables . - -**Parameters:** -* `euler_angle_1`, `euler_angle_2`, `euler_angle_3` (type: `Real`): Individual Euler angles . -* `read_prop_user_object` (type: `UserObjectName`): A `PropertyReadFile` user object to read Euler angles per element . -* `euler_angle_variables` (type: `std::vector`): Coupled variables providing Euler angles . - -### Rotation Tensors: Crystal-to-Sample Rotation - -The `RotationTensor` class is used to manage and apply rotations . The `ComputeElasticityTensorCP` material generates a "passive" rotation matrix from the Euler angles or a user-supplied rotation matrix . This matrix rotates the crystal slip system direction and plane normals into the user-specified orientation . - -**Equations:** -The rotation matrix $R$ can be directly provided or constructed from Euler angles. The documentation provides an example of a rotation matrix : -$$ -R = \begin{bmatrix} - \frac{\sqrt{2}}{2} & \frac{\sqrt{6}}{6} & \frac{\sqrt{3}}{3} \\ - -\frac{\sqrt{2}}{2} & \frac{\sqrt{6}}{6} & \frac{\sqrt{3}}{3} \\ - 0 & -\frac{\sqrt{6}}{3} & \frac{\sqrt{3}}{3} - \end{bmatrix} -$$ - -This matrix is used for a "passive" rotation, converting directions from the sample frame to the crystal frame . - -**Classes & Methods:** -* `ComputeElasticityTensorCP::assignEulerAngles()`: Assigns Euler angles from various sources (input file, `PropertyReadFile`, coupled variables) to a material property . -* `ComputeElasticityTensorCP::computeQpElasticityTensor()`: Computes the elasticity tensor, applying the crystal rotation matrix . -* `CrystalPlasticityStressUpdateBase::calculateSchmidTensor()`: Rotates slip system plane normal and direction vectors into the local crystal lattice orientation using the crystal rotation tensor . - -## GrainTracker and Polycrystal - -The `phase_field` module provides tools for managing polycrystal structures and assigning orientations to grains . - -### Assigning Orientations to Grains in a Polycrystal - -The `PolycrystalUserObjectBase` class serves as a base for creating polycrystal initial conditions and discovering grain structures . Derived classes like `PolycrystalEBSD` can reconstruct grain structures from EBSD data . - -**Classes & Methods:** -* `PolycrystalUserObjectBase::getGrainsBasedOnPoint()`: Retrieves active grain IDs based on a point in the mesh . -* `PolycrystalUserObjectBase::getNumGrains()`: Returns the number of grains in the polycrystal structure . -* `PolycrystalEBSD`: A user object for setting up a polycrystal structure from an EBSD Datafile . It uses an `EBSDReader` to get data for specific points . - -## EBSD Data Integration - -MOOSE can integrate experimental orientation maps through the `EBSDReader` and `PolycrystalEBSD` classes . - -### Reading Experimental Orientation Maps - -The `EBSDReader` user object is responsible for reading EBSD data . The `PolycrystalEBSD` class then uses this reader to assign grain IDs and phase information based on spatial points . - -**MOOSE Input Syntax:** -` ` `ini -[UserObjects] - [ebsd_reader] - type = EBSDReader - [] - [ebsd] - type = PolycrystalEBSD - coloring_algorithm = bt - ebsd_reader = ebsd_reader - enable_var_coloring = true - [] -[] -` ` ` - -This input block defines an `EBSDReader` named `ebsd_reader` and a `PolycrystalEBSD` object named `ebsd` that uses the reader to set up the polycrystal structure . - -## Texture Evolution - -MOOSE can track orientation changes during deformation, particularly through the `EulerAngleUpdater` class - -Wiki pages you might want to explore: -- [Physics Modules (idaholab/moose)](https://deepwiki.com/idaholab/moose#5) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-polycrystal.md b/packages/akms/src/akms/_bundled/global_nodes/moose-cp-polycrystal.md deleted file mode 100644 index 609fc3e..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-polycrystal.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -id: moose-cp-polycrystal -title: MOOSE Crystal plasticity polycrystal homogenization -domain: constitutive -subdomain: algorithmic -tags: -- polycrystal -- voronoi -- RVE -- periodic-bc -- volume-averaging -- homogenization -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-crystal-plasticity-advanced - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-crystal-plasticity-advanced ---- - -# MOOSE Crystal plasticity polycrystal homogenization - -MOOSE handles polycrystal simulations, particularly in the context of crystal plasticity and phase-field grain growth, primarily through its `phase_field` and `solid_mechanics` modules. - -### 1. Full-field (each element = one orientation) vs. homogenization approaches - -The provided context does not explicitly detail the distinction between full-field (each element = one orientation) and homogenization approaches for polycrystal simulations in crystal plasticity. However, the presence of `ComputePolycrystalElasticityTensor` suggests a full-field approach where elasticity can vary per grain, which implies per element if grains are resolved at the element level. The `CrystalPlasticityStressUpdateBase` and `FiniteStrainCrystalPlasticity` classes in the `solid_mechanics` module indicate that crystal plasticity models are implemented at the material point level, which is consistent with a full-field approach where each quadrature point within an element can have its own crystal orientation and plastic response. - -### 2. `PolycrystalElasticDrivingForce` and grain boundary energy contributions - -The provided context does not contain information about a class named `PolycrystalElasticDrivingForce`. However, the `Grain Growth Model` documentation discusses grain boundary energy contributions within the phase-field framework. The free energy functional $F$ includes a term $\kappa \sum^N_i |\nabla \eta_i|^2$ , which represents the gradient energy related to grain boundaries. The parameter $\kappa$ is defined in terms of the grain boundary energy $\sigma$ and diffuse grain boundary width $w_{GB}$ as $\kappa = \frac{3}{4} \sigma w_{GB}$ . The `GBEvolution` material defines these model parameters. - -### 3. Voronoi tessellation: `PolycrystalVoronoi` for initial grain structure generation - -MOOSE uses the `PolycrystalVoronoi` UserObject to generate initial polycrystal grain structures using Voronoi tessellation . This UserObject can either generate random points as grain centroids or read them from a file . - -**Classes & Methods:** -* `PolycrystalVoronoi::validParams()`: Defines the input parameters for the `PolycrystalVoronoi` UserObject . -* `PolycrystalVoronoi::PolycrystalVoronoi(const InputParameters & parameters)`: Constructor for the `PolycrystalVoronoi` class, which initializes parameters like the number of grains, random seed, and interface width . -* `PolycrystalVoronoi::getGrainsBasedOnPoint(const Point & point, std::vector & grains) const`: This method determines the grain(s) associated with a given spatial point . It can use a KD-tree for faster searching . -* `PolycrystalVoronoi::precomputeGrainStructure()`: Overridden method to precompute the grain structure . -* `PolycrystalVoronoi::buildSearchTree()`: Builds a KD-tree to speed up grain searches . - -**Parameters:** -* `grain_num`: `unsigned int`, default `0`. Number of grains to be represented by order parameters . -* `rand_seed`: `unsigned int`, default `0`. The random seed for grain generation . -* `columnar_3D`: `bool`, default `false`. Specifies if the 3D microstructure is columnar in the z-direction . -* `use_kdtree`: `bool`, default `false`. Enables the use of a KD-tree for faster grain searches . -* `point_patch_size`: `unsigned int`, default `1`. How many nearest points the KDTree should return . -* `grain_patch_size`: `unsigned int`, default `10`. How many nearest grains the KDTree should return . -* `file_name`: `FileName`, default `""`. Path to a file containing grain centroids . -* `int_width`: `Real`, default `0.0`. Width of diffuse interfaces . - -**MOOSE Input Syntax:** -` ` `ini -[UserObjects] - [voronoi] - type = PolycrystalVoronoi - grain_num = 12 # Number of grains - coloring_algorithm = jp - rand_seed = 10 - # use_kdtree = true # Uncomment to enable KDTree - [] -[] - -[ICs] - [PolycrystalICs] - [PolycrystalColoringIC] - polycrystal_ic_uo = voronoi - [] - [] -[] -` ` ` - -### 4. Coupling with phase field grain growth: how do CP and grain evolution interact? - -The `phase_field` module provides capabilities for microstructure evolution, including grain tracking and phase transformations . The `Grain Growth Model` documentation describes the Allen-Cahn equation used for grain evolution. - -Coupling between crystal plasticity and grain evolution can occur through: -* **Material properties**: The `ComputePolycrystalElasticityTensor` material in the `phase_field` module computes an evolving elasticity tensor coupled to a grain growth phase field model. This implies that the elastic properties used in crystal plasticity calculations can be influenced by the evolving grain structure. -* **UserObjects**: `PolycrystalUserObjectBase` and its derivatives like `PolycrystalVoronoi` provide information about the grain structure (e.g., grain IDs, centroids) that can be used by other modules. -* **Order Parameters**: The phase field model uses order parameters ($\eta_i$) to represent different grains . These order parameters can influence material properties, which in turn affect the crystal plasticity response. - -### 5. RVE (Representative Volume Element) computations: periodic BCs, volume averaging of stress/strain - -The use of periodic boundary conditions (BCs) is mentioned in the context of `PolycrystalVoronoiIC_periodic.i` and `PolycrystalHex` , indicating support for RVE computations. For example, `PolycrystalHex` explicitly checks for periodic BCs . The `PolycrystalUserObjectBase` also checks for consistent periodicity across coupled variables . - -The provided context does not explicitly detail volume averaging of stress/strain for RVE computations, but it is a common post-processing step in such simulations. - -### 6. Performance: how does MOOSE parallelize polycrystal CP simulations? - -MOOSE is designed for parallel execution, and this extends to polycrystal simulations. The `Physics Modules` wiki page mentions that module objects requiring parallel communication should use libMesh/PETSc communicator patterns . - -Specifically for `PolycrystalVoronoi`, the `use_kdtree` parameter is available to speed up grain searches, especially for a large number of grains . The `KDTree` is built a-priori to optimize the search time for nearest points and neighboring grains . - -The `distributed_poly_ic.i` test input file explicitly sets `parallel_type = distributed` for the mesh, indicating that polycrystal initial condition generation can be run in parallel. - -## Classes & Methods: - -* `PolycrystalVoronoi::validParams()`: Defines input parameters for Voronoi tessellation . -* `PolycrystalVoronoi::getGrainsBasedOnPoint()`: Determines grain(s) associated with a spatial point . -* `PolycrystalVoronoi::buildSearchTree()`: Constructs a KD-tree for efficient grain searching . -* `PolycrystalColoringIC::value()`: Returns the order parameter value for a given point based on the polycrystal user object . -* `PolycrystalUserObjectBase::initialSetup()`: Checks for consistent periodicity across coupled variables . -* `ComputePolycrystalElasticityTensor::computeQpElasticityTensor()`: Computes the elasticity tensor at a quadrature point, coupled to grain growth . -* `CrystalPlasticityStressUpdateBase::getSlipSystems()`: Reads and normalizes slip system vectors from a file . -* `FiniteStrainUObasedCP`: Material class for user-object-based finite strain crystal plasticity . - -## Equations: - -The grain growth model uses the Allen-Cahn equation for the evolution of each grain's order parameter: -$$ -\frac{\partial \eta_i}{\partial t} = - L \frac{\delta F}{\delta \eta_i} \quad (1) -$$ -where $F$ is the free energy functional, $L$ is the order parameter mobility, and $\delta$ represents a variational derivative. The free energy functional is given by: -$$ -F = \int_V f_{loc}(\eta_0, \eta_1, \ldots, \eta_N) + f_{add} (\eta_0, \eta_1, \ldots, \eta_N) + \kappa \sum^N_i |\nabla \eta_i|^2 \quad (2) -$$ - -Wiki pages you might want to explore: -- [Physics Modules (idaholab/moose)](https://deepwiki.com/idaholab/moose#5) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-stress-update.md b/packages/akms/src/akms/_bundled/global_nodes/moose-cp-stress-update.md deleted file mode 100644 index bb94756..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-stress-update.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: moose-cp-stress-update -title: MOOSE Crystal plasticity stress update algorithm -domain: constitutive -subdomain: algorithmic -tags: -- crystal-plasticity -- multiplicative-decomposition -- resolved-shear-stress -- plastic-velocity-gradient -- exponential-map -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-crystal-plasticity - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-crystal-plasticity -- to: cm-anisotropic-yield - type: implements - weight: 0.8 - note: CP stress update with slip system flow rules ---- - -# MOOSE Crystal plasticity stress update algorithm - -The MOOSE framework implements crystal plasticity primarily through the `CrystalPlasticityStressUpdateBase` class and its derived classes, such as `CrystalPlasticityKalidindiUpdate` and `ComputeMultipleCrystalPlasticityStress` . The implementation uses a multiplicative decomposition of the deformation gradient and an iterative Newton-Raphson approach to update the stress state and internal variables . - -## Multiplicative Decomposition $F = F^e \cdot F^p$ - -The crystal plasticity models in MOOSE utilize the multiplicative decomposition of the total deformation gradient $F$ into an elastic component $F^e$ and a plastic component $F^p$ . This decomposition is fundamental to the stress update algorithm, where the plastic deformation gradient `_plastic_deformation_gradient` is a stateful material property that is evolved over time . - -## `CrystalPlasticityStressUpdateBase` — Stress Update Algorithm - -The `CrystalPlasticityStressUpdateBase` class provides the foundational structure for crystal plasticity stress updates . Derived classes implement the specific constitutive laws. The stress update involves an iterative process to converge the stress state and internal variables . - -### Algorithm Steps - -The overall stress update is handled by `ComputeMultipleCrystalPlasticityStress::computeQpStress()` , which calls `solveQp()` to perform the iterative solution. - -#### a. Trial Elastic Deformation Gradient: $F^e_{trial} = F \cdot (F^p_{old})^{-1}$ - -The trial elastic deformation gradient is implicitly calculated within the stress update. The `_plastic_deformation_gradient_old` and `_deformation_gradient` (current total deformation gradient) are used to compute the elastic response . - -#### b. Resolved Shear Stress on each Slip System: $\tau^\alpha = \Sigma_{ij} (S^e_{ij} \cdot s^\alpha_i \cdot m^\alpha_j)$ - -The resolved shear stress $\tau^\alpha$ on each slip system is calculated by the `CrystalPlasticityStressUpdateBase::calculateShearStress()` method . This method takes the PK2 stress and other deformation gradient components to compute `_tau`, which stores the applied shear stress for each slip system . The Schmid tensor, which involves the slip direction `_slip_direction` and slip plane normal `_slip_plane_normal`, is computed by `calculateSchmidTensor()` . - -#### c. Flow Rule: $\dot{\gamma}^\alpha = \dot{\gamma}_0 \cdot |\tau^\alpha/g^\alpha|^n \cdot \text{sign}(\tau^\alpha)$ (power law) - -A common power law flow rule is used in several crystal plasticity models, such as `CrystalPlasticityKalidindiUpdate` and `FiniteStrainCrystalPlasticity` . The parameters involved are: -* $\dot{\gamma}_0$: Reference slip rate . -* $\tau^\alpha$: Applied shear stress on slip system $\alpha$ . -* $g^\alpha$: Slip system strength or resistance to slip . -* $n$ (or $1/m$): Strain rate sensitivity exponent . - -The `calculateSlipRate()` virtual method in `CrystalPlasticityStressUpdateBase` is responsible for computing the slip increment based on the constitutive model defined in child classes . - -#### d. Plastic Velocity Gradient: $L^p = \Sigma^\alpha \dot{\gamma}^\alpha \cdot s^\alpha \otimes m^\alpha$ - -The plastic velocity gradient is constructed from the sum of contributions from each slip system. The `_flow_direction` property, which is a `std::vector`, stores the Schmid tensors ($s^\alpha \otimes m^\alpha$) for each slip system . The slip rates `_slip_increment` are calculated and used in conjunction with `_flow_direction` to update the plastic deformation . - -#### e. Update $F^p$ via exponential map or forward Euler - -The update of $F^p$ is handled internally within the stress update routines. While the prompt mentions exponential map or forward Euler, the documentation for `ComputeMultipleCrystalPlasticityStress` states that "Backward Euler integration rule is used for the rate equations" . - -#### f. Newton Iteration to converge the stress state - -The stress state is converged using a Newton-Raphson iteration. The `ComputeMultipleCrystalPlasticityStress` class explicitly mentions solving the "PK2 stress residual equation using Newton - Raphson" . The `calculateResidualAndJacobian()` method is called to compute the residual `_residual_tensor` and Jacobian `_jacobian` . The `solveStress()` method performs the actual stress update . - -## Convergence Criterion for the Crystal Plasticity Inner Loop - -The convergence of the crystal plasticity inner loop, which involves the stress state and internal variables, is controlled by several tolerances: -* `_rtol`: Stress residual equation relative tolerance . -* `_abs_tol`: Stress residual equation absolute tolerance . -* `_rel_state_var_tol` (`stol`): Constitutive internal state variable relative change tolerance . -* `_slip_incr_tol`: Maximum allowable slip in an increment for each individual constitutive model . -* `_resistance_tol`: Constitutive slip system resistance relative residual tolerance . -* `_zero_tol`: Tolerance for residual check when variable value is zero . - -The `areConstitutiveStateVariablesConverged()` virtual method in `CrystalPlasticityStressUpdateBase` is used to determine if all state variables have converged . - -## Slip System Geometries (FCC, BCC, HCP) - -Slip system geometries are defined by reading data from a file specified by `slip_sys_file_name` . The `CrystalPlasticityStressUpdateBase::getSlipSystems()` method handles reading and processing this data . - -* **Crystal Lattice Type**: The `crystal_lattice_type` parameter, an `MooseEnum`, specifies the lattice type (BCC, FCC, HCP) . -* **Miller Indices / Miller-Bravais**: For BCC and FCC crystals, slip plane normals and directions are read directly from the file and scaled by `_unit_cell_dimension` . For HCP crystals, a transformation from Miller-Bravais 4-index notation to a 3-index Cartesian representation is performed by `transformHexagonalMillerBravaisSlipSystems()` . This transformation also includes checks to ensure that the Miller-Bravais indices for the basal plane sum to zero . -* **Unit Cell Dimensions**: The `unit_cell_dimension` parameter allows specifying the dimensions of the unit cell, which are used in scaling the slip system vectors . - -### Classes & Methods - -* `CrystalPlasticityStressUpdateBase::validParams()`: Defines input parameters common to all crystal plasticity stress update materials . -* `CrystalPlasticityStressUpdateBase::getSlipSystems()`: Reads slip system data from a file and normalizes vectors . -* `CrystalPlasticityStressUpdateBase::transformHexagonalMillerBravaisSlipSystems()`: Transforms HCP Miller-Bravais indices to Cartesian coordinates . -* `CrystalPlasticityStressUpdateBase::calculateShearStress()`: Computes the resolved shear stress for each slip system . -* `CrystalPlasticityStressUpdateBase::calculateSlipRate()`: Virtual method to calculate the slip increment based on the constitutive model . -* `CrystalPlasticityStressUpdateBase::areConstitutiveStateVariablesConver - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-twinning.md b/packages/akms/src/akms/_bundled/global_nodes/moose-cp-twinning.md deleted file mode 100644 index e76ca33..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-cp-twinning.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: moose-cp-twinning -title: MOOSE Crystal plasticity twinning and phase transformation -domain: constitutive -subdomain: algorithmic -tags: -- twinning -- phase-transformation -- TRIP -- volume-fraction -- reorientation -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-crystal-plasticity-advanced - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-crystal-plasticity-advanced ---- - -# MOOSE Crystal plasticity twinning and phase transformation - -The MOOSE crystal plasticity module supports deformation twinning through the `CrystalPlasticityTwinningKalidindiUpdate` class, which implements a Kalidindi-based twinning propagation model for FCC and HCP materials . This module tracks the volume fraction of twinned regions and can be coupled with dislocation slip models . However, it does not explicitly support stress-induced phase transformations (TRIP implementations) or reorientation of the crystal lattice due to twinning . - -## Deformation Twinning - -### Classes & Methods - -* `CrystalPlasticityTwinningKalidindiUpdate` : A material model that computes plastic shear increment due to twinning based on Kalidindi's model . - * `CrystalPlasticityTwinningKalidindiUpdate::validParams()`: Defines the input parameters for the twinning model . - * `CrystalPlasticityTwinningKalidindiUpdate::initQpStatefulProperties()`: Initializes stateful material properties, including twin volume fractions and slip resistance . - * `CrystalPlasticityTwinningKalidindiUpdate::calculateSlipRate()`: Computes the plastic shear increment due to twinning using a power law constitutive model . - * `CrystalPlasticityTwinningKalidindiUpdate::calculateStateVariableEvolutionRateComponent()`: Calculates the rate of twin volume fraction on each twin system . - * `CrystalPlasticityTwinningKalidindiUpdate::calculateTwinVolumeFraction()`: Updates the twin volume fraction for each system and the total twin volume fraction . - * `CrystalPlasticityTwinningKalidindiUpdate::calculateTwinResistance()`: Calculates the twin propagation resistance based on coplanar and non-coplanar hardening coefficients . - -### Twin Systems: Definition - -Twin systems are defined similarly to slip systems by providing a `slip_sys_file_name` parameter, which specifies the crystallographic orientations for twinning . The `CrystalPlasticityTwinningKalidindiUpdate` class uses these definitions to calculate resolved shear stresses and plastic shear increments . - -### Volume Fraction Tracking for Twinned Regions - -The module tracks the volume fraction of twinned regions on each twin system and the total twin volume fraction . -The total twin volume fraction is stored in the material property `_total_twin_volume_fraction` , and individual twin system volume fractions are stored in `_twin_volume_fraction` . An upper limit for the total twin volume fraction can be set using the `upper_limit_twin_volume_fraction` parameter . - -### Reorientation of the Crystal Lattice Due to Twinning - -The current implementation of `CrystalPlasticityTwinningKalidindiUpdate` does not explicitly support reorientation of the crystal lattice due to twinning . The model focuses on the propagation of twins and their contribution to plastic deformation and hardening . - -### Transformation Plasticity (TRIP) Implementations - -The MOOSE crystal plasticity module, specifically `CrystalPlasticityTwinningKalidindiUpdate`, does not include implementations for stress-induced phase transformations (TRIP) . Its scope is limited to deformation twinning and dislocation slip . - -### Interaction Between Slip and Twin Systems — Latent Hardening Across Mechanisms - -The interaction between slip and twin systems is handled by modifying the plastic velocity gradient calculation . When both twinning and dislocation slip models are included, the plastic velocity gradient ($L^P$) is calculated as a weighted sum of contributions from both mechanisms : - -$$ -L^P = \left(1 - {f_{total}}_{(n-1)} \right) \sum_{\alpha}^{slip} \dot{\gamma}^{\alpha} S^{\alpha}_o + \sum_{\beta}^{twin} \dot{f}^{\beta}\gamma_{tw}S^{\beta}_o \quad (1) -$$ - -Here, $f_{total}$ is the total twin volume fraction, $\dot{\gamma}^{\alpha}$ is the plastic shear rate due to dislocation slip, $S^{\alpha}_o$ is the Schmid tensor for slip systems, $\dot{f}^{\beta}$ is the rate of twin volume fraction, and $S^{\beta}_o$ is the Schmid tensor for twinning systems . The total twin volume fraction from the previous timestep, $f_{total(n-1)}$, is used to couple the models . - -Latent hardening across mechanisms is implemented through the twin propagation resistance calculation, which considers different hardening coefficients for non-coplanar and coplanar twinning systems . - -$$ -\Delta g^{\beta} = \gamma_{tw} \left[ h_{nc}\left( f_{total} \right)^b \sum_{nc}^k \dot{f}^k + h_{cp}\left( f_{total} \right) \sum_{cp}^k \dot{f}^k \right] \quad (2) -$$ - -where $h_{nc}$ is the non-coplanar hardening coefficient, $b$ is the hardening exponent, and $h_{cp}$ is the coplanar hardening coefficient . - -### Parameters - -The `CrystalPlasticityTwinningKalidindiUpdate` class exposes several parameters for configuring the twinning model : - -* `initial_total_twin_volume_fraction = 0.0` (Real): Initial sum of twin volume fraction across all systems . -* `twin_reference_strain_rate = 1.0e-3` (Real): Reference strain rate ($\gamma_o$) for the power law . -* `twin_strain_rate_sensitivity_exponent = 0.05` (Real): Strain rate sensitivity exponent ($m$) . -* `characteristic_twin_shear = 1.0 / std::sqrt(2.0)` (Real): Characteristic shear of the twin ($\gamma_{tw}$) . -* `initial_twin_lattice_friction = 0.0` (Real): Initial lattice friction for twin propagation . -* `non_coplanar_coefficient_twin_hardening = 8000.0` (Real): Hardening coefficient for non-coplanar twin systems ($h_{nc}$) . -* `coplanar_coefficient_twin_hardening = 800.0` (Real): Hardening coefficient for coplanar twin systems ($h_{cp}$) . -* `non_coplanar_twin_hardening_exponent = 0.05` (Real): Hardening exponent for non-coplanar twin systems ($b$) . -* `upper_limit_twin_volume_fraction = 0.8` (Real): Maximum allowed total twin volume fraction ($f_{limit}$) . - -### MOOSE Input Syntax - -An example of how to configure the `CrystalPlasticityTwinningKalidindiUpdate` material model in a MOOSE input file is shown below : - -` ` `ini -[Materials] - [twin_only_xtalpl] - type = CrystalPlasticityTwinningKalidindiUpdate - number_slip_systems = 12 - slip_sys_file_name = 'fcc_input_twinning_systems.txt' - initial_twin_lattice_friction = 1.5 - upper_limit_twin_volume_fraction = 1e-7 - stol = 0.01 - print_state_variable_convergence_error_messages = true - [] -[] -` ` ` - -To couple twinning with dislocation slip, the `total_twin_volume_fraction` property from the twinning model must be provided to the slip model : - -` ` `ini -[Materials] - [slip_xtalpl] - type = CrystalPlasticityKalidindiUpdate - number_slip_systems = 12 - slip_sys_file_name = input_slip_sys.txt - total_twin_volume_fraction = 'twin_total_volume_fraction_twins' - [] -[] -` ` ` - -## Notes - -The `CrystalPlasticityTwinningKalidindiUpdate` model is based on the Kalidindi (2001) constitutive model . It does not allow for de-twinning - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-creep-models.md b/packages/akms/src/akms/_bundled/global_nodes/moose-creep-models.md deleted file mode 100644 index 77f248b..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-creep-models.md +++ /dev/null @@ -1,196 +0,0 @@ ---- -id: moose-creep-models -title: MOOSE Creep model implementations in MOOSE -domain: constitutive -subdomain: algorithmic -tags: -- power-law-creep -- hyperbolic-sine-creep -- activation-energy -- temperature-coupling -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-creep-viscoplasticity - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-creep-viscoplasticity -- to: cm-viscoplastic-thermo - type: implements - weight: 0.9 - note: Power law and sinh creep implementations ---- - -# MOOSE Creep model implementations in MOOSE - -This response addresses MOOSE's creep model implementations, specifically `PowerLawCreepStressUpdate` and `HyperbolicSinCreepStressUpdate`, focusing on their constitutive equations, parameter handling, residual and derivative computations for return mapping, time integration, temperature coupling, and how multiple creep mechanisms are combined. - -## 1. `PowerLawCreepStressUpdate` - -### Creep Rate Equation -The `PowerLawCreepStressUpdate` class implements a power law creep model. The creep rate equation is given by: -$$ -\dot{\epsilon} = \left( \sigma^{trial}_{effective} - 3 G \Delta p \right)^n \exp \left( \frac{-Q}{RT} \right) \left(t - t_o \right)^m \quad (1) -$$ -Here, $\sigma^{trial}_{effective}$ is the scalar von Mises trial stress, $G$ is the isotropic shear modulus, $Q$ is the activation energy, $R$ is the universal gas constant, $T$ is the temperature, $t$ and $t_o$ are the current and initial times, respectively, and $n$ and $m$ are exponent values. - -### Parameter Handling -The activation energy, stress exponent, and prefactor are handled as follows: -* **Activation Energy (`Q`)**: This is provided via the `activation_energy` parameter. It is used in the exponential term $\exp \left( \frac{-Q}{RT} \right)$. -* **Stress Exponent (`n`)**: This is specified by the `n_exponent` parameter. It is the exponent on the effective stress term $(\sigma^{trial}_{effective} - 3 G \Delta p)$. -* **Prefactor**: The leading coefficient in the power-law equation is given by the `coefficient` parameter. Additionally, there is an exponent on time, `m_exponent`, which acts as part of the prefactor, $(t - t_o)^m$. - -### Parameters - -` ` `ini -[./creep] - type = ADPowerLawCreepStressUpdate - activation_energy = 4e4 - temperature = 1200 - coefficient = 1e-18 - gas_constant = 1.987 - n_exponent = 3 - base_name = 'creep' - outputs = all -[../] -` ` ` - -## 2. `HyperbolicSinCreepStressUpdate` - -The provided codebase context does not contain information about `HyperbolicSinCreepStressUpdate`. Therefore, I cannot describe its sinh law formulation and parameters. - -## 3. `computeResidual()` and `computeDerivative()` for Return Mapping - -These models compute `computeResidual()` and `computeDerivative()` as part of an implicit integration algorithm for radial return stress updates. The `PowerLawCreepStressUpdate` class inherits from `RadialReturnCreepStressUpdateBaseTempl` and defines these methods. - -### `PowerLawCreepStressUpdate::computeResidual()` -This method calculates the residual for the implicit integration. The residual equation typically involves the difference between the calculated creep strain increment and the inelastic strain multiplier (`scalar`). - -### `PowerLawCreepStressUpdate::computeDerivative()` -This method computes the derivative of the residual with respect to the inelastic strain multiplier, which is crucial for the Newton-Raphson iteration in the return mapping algorithm. - -## 4. Time Integration: How Δt enters the Residual Equation - -The time step $\Delta t$ enters the residual equation by multiplying the creep rate to obtain the creep strain increment. For instance, in the `HillCreepStressUpdate` (which is an anisotropic extension of Power Law Creep), the residual is formed as `creep_rate * _dt - delta_gamma`. This `_dt` member variable represents the current time step. - -## 5. Temperature Coupling: How the Creep Model Gets Temperature - -The creep models obtain temperature from a thermal solve by coupling a temperature variable. The `_temperature` member in `PowerLawCreepStressUpdateTempl` is a `GenericVariableValue` that holds the temperature value. This temperature is then used to calculate the exponential term in the creep rate equation. - -### Parameters - -` ` `ini -temperature = temp -` ` ` -The `temperature` parameter is used to specify the coupled temperature variable. - -## 6. Multiple Creep Mechanisms - -MOOSE combines parallel creep mechanisms using classes like `ComputeMultipleInelasticStress` or `ComputeCreepPlasticityStress`. - -### `ComputeCreepPlasticityStress` -This class is designed to combine one creep model and one plasticity model. It forms a system of residual equations for both creep and plasticity and solves them simultaneously using a combined Newton iteration. - -The residual equations for combined creep and plasticity are: -$$ -f_c = \dot{p}_c \Delta t - \Delta p_c = 0 \quad (2) -$$ -$$ -f_p = \sigma^{tr}_e - 3G(\Delta p_c + \Delta p_p)-r-\sigma_y=0 \quad (3) -$$ -These are then solved using a Jacobian matrix containing partial derivatives of $f_c$ and $f_p$ with respect to $\Delta p_c$ and $\Delta p_p$. - -### `ADMultiplePowerLawCreepStressUpdate` -For multiple power law creep expressions, the `ADMultiplePowerLawCreepStressUpdate` class allows defining different sets of power law parameters (coefficient, n_exponent, m_exponent, activation_energy) for different von Mises stress intervals. During the return mapping, the appropriate set of parameters is selected based on the effective trial stress. - -### Parameters - -` ` `cpp - /// Leading coefficient vector - const std::vector _coefficient; - - /// Exponent on the effective stress vector - const std::vector _n_exponent; - - /// Exponent on time vector - const std::vector _m_exponent; - - /// Stress thresholds vector - const std::vector _stress_thresholds; - - /// Activation energy for exp term vector - const std::vector _activation_energy; -` ` ` - -## Classes & Methods - -* `PowerLawCreepStressUpdateTempl::computeResidual(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the residual for the power law creep model. -* `PowerLawCreepStressUpdateTempl::computeDerivative(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the derivative of the residual for the power law creep model. -* `HillCreepStressUpdateTempl::computeResidual(...)`: Computes the residual for the anisotropic Hill creep model, which is an extension of the power law creep. -* `HillCreepStressUpdateTempl::computeDerivative(...)`: Computes the derivative of the residual for the anisotropic Hill creep model. -* `ADMultiplePowerLawCreepStressUpdate::stressIndex(const ADReal & effective_trial_stress)`: Determines which set of power law parameters to use based on the effective trial stress. -* `ComputeCreepPlasticityStress::initialSetup()`: Initializes the creep and plasticity models and checks for compatibility. -* `ComputeCreepPlasticityStress::updateQpState(...)`: Orchestrates the computation of inelastic strain increments for combined creep and plasticity. - -## Relationships - -` ` `mermaid -classDiagram - class RadialReturnCreepStressUpdateBaseTempl { - +computeResidual() - +computeDerivative() - } - class PowerLawCreepStressUpdateTempl { - +PowerLawCreepStressUpdateTempl() - +computeResidual() - +computeDerivative() - -_temperature - -_coefficient - -_n_exponent - -_m_exponent - -_activation_energy - -_gas_constant - -_start_time - } - class ADMultiplePowerLawCreepStressUpdate { - +ADMultiplePowerLawCreepStressUpdate() - +computeResidual() - +computeDerivative() - +stressIndex() - -_temperature - -_coefficient[] - -_n_exponent[] - -_m_exponent[] - -_stress_thresholds[] - -_activation_energy[] - -_gas_constant - -_start_time - } - class ComputeMultipleInelasticStress { - +addInelasticModel() - } - class ComputeCreepPlasticityStress { - +ComputeCreepPlasticityStress() - +initialSetup() - +updateQpState() - -_creep_model - -_plasticity_model - } - - RadialReturnCreepStressUpdateBaseTempl <|-- PowerLawCreepStressUpdateTempl : inherits - ADRadialReturnCreepStressUpdateBase <|-- ADMultiplePowerLawCreepStressUpdate : inherits - ComputeMultipleInelasticStress <|-- ComputeCreepPlasticityStress : inherits - ComputeCreepPlasticityStress --> PowerLawCreepStressUpdateTempl : uses - ComputeCreepPlasticityStress --> IsotropicPlasticityStressUpdate : uses -` ` ` - -## Notes - -The codebase does not contain any explicit implementation or documentation for `HyperbolicSinCreepStressUpdate`. The closest related class found is `PowerLawCreepStressUpdate`, and its anisotropic extension `HillCreepStressUpdate`. The discussion on multiple creep mechanisms primarily refers to combining different types of inelastic models (creep and plasticity) or using multiple power-law expressions based on stress thresholds. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-creep-viscoplasticity.md b/packages/akms/src/akms/_bundled/global_nodes/moose-creep-viscoplasticity.md deleted file mode 100644 index c9de965..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-creep-viscoplasticity.md +++ /dev/null @@ -1,285 +0,0 @@ ---- -id: moose-creep-viscoplasticity -title: MOOSE Creep and Viscoplasticity Models -domain: constitutive -subdomain: algorithmic -tags: -- creep -- viscoplasticity -- power-law -- hyperbolic-sine -- temperature-coupling -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-stress-computation-chain - type: requires - weight: 0.7 - note: Part of the stress computation dispatch chain -- to: moose-return-mapping-base - type: requires - weight: 0.9 - note: Creep models use return mapping solver -- to: cm-viscoplastic-thermo - type: implements - weight: 0.9 - note: Implements power law creep and viscoplastic flow rules ---- - -# MOOSE Creep and Viscoplasticity Models - -Framework knowledge node covering 2 aspect(s) of Creep and Viscoplasticity Models. - -## Creep model implementations in MOOSE - -This response addresses MOOSE's creep model implementations, specifically `PowerLawCreepStressUpdate` and `HyperbolicSinCreepStressUpdate`, focusing on their constitutive equations, parameter handling, residual and derivative computations for return mapping, time integration, temperature coupling, and how multiple creep mechanisms are combined. - -## 1. `PowerLawCreepStressUpdate` - -### Creep Rate Equation -The `PowerLawCreepStressUpdate` class implements a power law creep model. The creep rate equation is given by: -$$ -\dot{\epsilon} = \left( \sigma^{trial}_{effective} - 3 G \Delta p \right)^n \exp \left( \frac{-Q}{RT} \right) \left(t - t_o \right)^m \quad (1) -$$ -Here, $\sigma^{trial}_{effective}$ is the scalar von Mises trial stress, $G$ is the isotropic shear modulus, $Q$ is the activation energy, $R$ is the universal gas constant, $T$ is the temperature, $t$ and $t_o$ are the current and initial times, respectively, and $n$ and $m$ are exponent values. - -### Parameter Handling -The activation energy, stress exponent, and prefactor are handled as follows: -* **Activation Energy (`Q`)**: This is provided via the `activation_energy` parameter. It is used in the exponential term $\exp \left( \frac{-Q}{RT} \right)$. -* **Stress Exponent (`n`)**: This is specified by the `n_exponent` parameter. It is the exponent on the effective stress term $(\sigma^{trial}_{effective} - 3 G \Delta p)$. -* **Prefactor**: The leading coefficient in the power-law equation is given by the `coefficient` parameter. Additionally, there is an exponent on time, `m_exponent`, which acts as part of the prefactor, $(t - t_o)^m$. - -### Parameters - -` ` `ini -[./creep] - type = ADPowerLawCreepStressUpdate - activation_energy = 4e4 - temperature = 1200 - coefficient = 1e-18 - gas_constant = 1.987 - n_exponent = 3 - base_name = 'creep' - outputs = all -[../] -` ` ` - -## 2. `HyperbolicSinCreepStressUpdate` - -The provided codebase context does not contain information about `HyperbolicSinCreepStressUpdate`. Therefore, I cannot describe its sinh law formulation and parameters. - -## 3. `computeResidual()` and `computeDerivative()` for Return Mapping - -These models compute `computeResidual()` and `computeDerivative()` as part of an implicit integration algorithm for radial return stress updates. The `PowerLawCreepStressUpdate` class inherits from `RadialReturnCreepStressUpdateBaseTempl` and defines these methods. - -### `PowerLawCreepStressUpdate::computeResidual()` -This method calculates the residual for the implicit integration. The residual equation typically involves the difference between the calculated creep strain increment and the inelastic strain multiplier (`scalar`). - -### `PowerLawCreepStressUpdate::computeDerivative()` -This method computes the derivative of the residual with respect to the inelastic strain multiplier, which is crucial for the Newton-Raphson iteration in the return mapping algorithm. - -## 4. Time Integration: How Δt enters the Residual Equation - -The time step $\Delta t$ enters the residual equation by multiplying the creep rate to obtain the creep strain increment. For instance, in the `HillCreepStressUpdate` (which is an anisotropic extension of Power Law Creep), the residual is formed as `creep_rate * _dt - delta_gamma`. This `_dt` member variable represents the current time step. - -## 5. Temperature Coupling: How the Creep Model Gets Temperature - -The creep models obtain temperature from a thermal solve by coupling a temperature variable. The `_temperature` member in `PowerLawCreepStressUpdateTempl` is a `GenericVariableValue` that holds the temperature value. This temperature is then used to calculate the exponential term in the creep rate equation. - -### Parameters - -` ` `ini -temperature = temp -` ` ` -The `temperature` parameter is used to specify the coupled temperature variable. - -## 6. Multiple Creep Mechanisms - -MOOSE combines parallel creep mechanisms using classes like `ComputeMultipleInelasticStress` or `ComputeCreepPlasticityStress`. - -### `ComputeCreepPlasticityStress` -This class is designed to combine one creep model and one plasticity model. It forms a system of residual equations for both creep and plasticity and solves them simultaneously using a combined Newton iteration. - -The residual equations for combined creep and plasticity are: -$$ -f_c = \dot{p}_c \Delta t - \Delta p_c = 0 \quad (2) -$$ -$$ -f_p = \sigma^{tr}_e - 3G(\Delta p_c + \Delta p_p)-r-\sigma_y=0 \quad (3) -$$ -These are then solved using a Jacobian matrix containing partial derivatives of $f_c$ and $f_p$ with respect to $\Delta p_c$ and $\Delta p_p$. - -### `ADMultiplePowerLawCreepStressUpdate` -For multiple power law creep expressions, the `ADMultiplePowerLawCreepStressUpdate` class allows defining different sets of power law parameters (coefficient, n_exponent, m_exponent, activation_energy) for different von Mises stress intervals. During the return mapping, the appropriate set of parameters is selected based on the effective trial stress. - -### Parameters - -` ` `cpp - /// Leading coefficient vector - const std::vector _coefficient; - - /// Exponent on the effective stress vector - const std::vector _n_exponent; - - /// Exponent on time vector - const std::vector _m_exponent; - - /// Stress thresholds vector - const std::vector _stress_thresholds; - - /// Activation energy for exp term vector - const std::vector _activation_energy; -` ` ` - -## Classes & Methods - -* `PowerLawCreepStressUpdateTempl::computeResidual(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the residual for the power law creep model. -* `PowerLawCreepStressUpdateTempl::computeDerivative(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the derivative of the residual for the power law creep model. -* `HillCreepStressUpdateTempl::computeResidual(...)`: Computes the residual for the anisotropic Hill creep model, which is an extension of the power law creep. -* `HillCreepStressUpdateTempl::computeDerivative(...)`: Computes the derivative of the residual for the anisotropic Hill creep model. -* `ADMultiplePowerLawCreepStressUpdate::stressIndex(const ADReal & effective_trial_stress)`: Determines which set of power law parameters to use based on the effective trial stress. -* `ComputeCreepPlasticityStress::initialSetup()`: Initializes the creep and plasticity models and checks for compatibility. -* `ComputeCreepPlasticityStress::updateQpState(...)`: Orchestrates the computation of inelastic strain increments for combined creep and plasticity. - -## Relationships - -` ` `mermaid -classDiagram - class RadialReturnCreepStressUpdateBaseTempl { - +computeResidual() - +computeDerivative() - } - class PowerLawCreepStressUpdateTempl { - +PowerLawCreepStressUpdateTempl() - +computeResidual() - +computeDerivative() - -_temperature - -_coefficient - -_n_exponent - -_m_exponent - -_activation_energy - -_gas_constant - -_start_time - } - class ADMultiplePowerLawCreepStressUpdate { - +ADMultiplePowerLawCreepStressUpdate() - +computeResidual() - +computeDerivative() - +stressIndex() - -_temperature - -_coefficient[] - -_n_exponent[] - -_m_exponent[] - -_stress_thresholds[] - -_activation_energy[] - -_gas_constant - -_start_time - } - class ComputeMultipleInelasticStress { - +addInelasticModel() - } - class ComputeCreepPlasticityStress { - +ComputeCreepPlasticityStress() - +initialSetup() - +updateQpState() - -_creep_model - -_plasticity_model - } - - RadialReturnCreepStressUpdateBaseTempl <|-- PowerLawCreepStressUpdateTempl : inherits - ADRadialReturnCreepStressUpdateBase <|-- ADMultiplePowerLawCreepStressUpdate : inherits - ComputeMultipleInelasticStress <|-- ComputeCreepPlasticityStress : inherits - ComputeCreepPlasticityStress --> PowerLawCreepStressUpdateTempl : uses - ComputeCreepPlasticityStress --> IsotropicPlasticityStressUpdate : uses -` ` ` - -## Notes - -The codebase does not contain any explicit implementation or documentation for `HyperbolicSinCreepStressUpdate`. The closest related class found is `PowerLawCreepStressUpdate`, and its anisotropic extension `HillCreepStressUpdate`. The discussion on multiple creep mechanisms primarily refers to combining different types of inelastic models (creep and plasticity) or using multiple power-law expressions based on stress thresholds. - - -## Viscoplastic flow rules and rate-dependent plasticity - -MOOSE implements rate-dependent (viscoplastic) flow rules through several material classes, primarily `ADViscoplasticityStressUpdate` and `HyperbolicViscoplasticityStressUpdate` , which are designed to work within the `ComputeMultipleInelasticStress` framework . These classes handle the iterative solution for inelastic strain increments. - -## ADViscoplasticityStressUpdate and its Formulation - -The `ADViscoplasticityStressUpdate` class is a material model that calculates stress updates for viscoplastic materials using automatic differentiation. It inherits from `ADViscoplasticityStressUpdateBase` and `ADSingleVariableReturnMappingSolution` . The core of its formulation involves solving for the inelastic strain increment through a return mapping algorithm. - -### Perzyna-type and Norton-type Flow Rules - -`ADViscoplasticityStressUpdate` supports different viscoplastic models, specified by the `_model` enum . Currently, it explicitly lists `LPS` (presumably a form of power-law creep) and `GTN` (Gurson-Tvergaard-Needleman) models . The `_power` parameter and `_coefficient` are used to define the power-law relationship. - -A Norton-type power-law creep is exemplified in the `lps_dual.i` test case , where the `power` parameter is set to `3` and `1` respectively for two different models. The `coefficient` can be a constant or a material property, as shown in the example where `coef_3` is a temperature-dependent expression . - -For Perzyna-type viscoplasticity, the `NEML2` framework provides `PerzynaPlasticFlowRate` . This class takes `reference_stress` and `exponent` as parameters . - -### Overstress Functions: Yield Function Integration - -The `ADViscoplasticityStressUpdate` class calculates a residual in `computeResidual` which is driven to zero during the return mapping iterations. This residual implicitly incorporates the overstress concept, where viscoplastic flow occurs when the stress state exceeds a yield-like surface. The `effective_trial_stress` is a key input to this residual calculation . - -In the `NEML2` framework, the yield function is explicitly defined by classes like `YieldFunction` . The `flow` model can then be composed of `overstress`, `vonmises`, and `yield` models . The `Normality` class then uses this `flow` model to define the plastic flow direction. - -For `HyperbolicViscoplasticityStressUpdate` , the constitutive equation for scalar plastic strain rate is given by: -$$\dot{p} = \phi (\sigma_e , r) = \alpha \sinh \beta (\sigma_e -r - \sigma_y)$$ -Here, $\sigma_e$ is the effective stress, $r$ is a hardening variable, and $\sigma_y$ is the yield stress. The parameters `_c_alpha` and `_c_beta` correspond to $\alpha$ and $\beta$ respectively. The `computeResidual` method in this class is responsible for solving this equation. - -## Interaction with ComputeMultipleInelasticStress Framework - -The `ComputeMultipleInelasticStress` class is designed to combine multiple inelastic stress calculations, such as creep and plasticity . It iterates over individual inelastic models, which are typically derived from `StressUpdateBase` , until the change in stress converges . - -The `ADViscoplasticityStressUpdate` and `HyperbolicViscoplasticityStressUpdate` classes are examples of such inelastic models. They are configured as sub-materials within `ComputeMultipleInelasticStress` . The `updateQpState` method in `ComputeMultipleInelasticStress` orchestrates the iterative solution, calling the `updateState` method of each inelastic model . - -## Classes & Methods - -* `ADViscoplasticityStressUpdate::updateState()` : Updates the stress and inelastic strain increment for viscoplastic materials. -* `ADViscoplasticityStressUpdate::computeResidual()` : Computes the residual for the return mapping iteration. -* `HyperbolicViscoplasticityStressUpdate::computeResidual()` : Computes the residual for the hyperbolic sine viscoplasticity model. -* `ComputeMultipleInelasticStress::updateQpState()` : Manages the iterative update of stress and inelastic strains for multiple inelastic models. -* `HEVPFlowRatePowerLawJ2::computeValue()` : Calculates the flow rate based on a power-law relationship for hyperelastic viscoplasticity. - -## Equations - -### Hyperbolic Viscoplasticity Strain Rate -The constitutive equation for scalar plastic strain rate in `HyperbolicViscoplasticityStressUpdate` is: -$$ \dot{p} = \alpha \sinh \beta (\sigma_e -r - \sigma_y) $$ -where: -* $\dot{p}$ is the scalar plastic strain rate. -* $\alpha$ is the viscoplasticity coefficient (`_c_alpha`). -* $\beta$ is the viscoplasticity coefficient inside the hyperbolic sine function (`_c_beta`). -* $\sigma_e$ is the effective stress. -* $r$ is the hardening variable. -* $\sigma_y$ is the yield stress (`_yield_stress`). - -### Power Law Flow Rate (HEVP) -The flow rate in `HEVPFlowRatePowerLawJ2` is calculated as: -$$ \text{val} = \left(\frac{\text{eqv\_stress}}{\text{_strength[qp]}}\right)^{\text{_flow\_rate\_exponent}} \times \text{_ref\_flow\_rate} $$ -where: -* `eqv_stress` is the equivalent stress. -* `_strength[qp]` is the material strength at the quadrature point. -* `_flow_rate_exponent` is the power law exponent. -* `_ref_flow_rate` is the reference flow rate. - -## Parameters - -* `ADViscoplasticityStressUpdate` : - * `coefficient`: `ADMaterialProperty` (e.g., `coef_3 = '0.5e-18 * exp(-4e4 / 1.987 / temp)'`) - * `power`: `Real` (e.g., `3`, `1`) - * `base_name`: `String` (e.g., `'lps_1'`) -* `HyperbolicViscoplasticityStressUpdate` : - * `yield_stress`: `Real` (required) - * `hardening_constant`: `Real` (required) - * `c_alpha`: `Real` (required, viscoplasticity coefficient) - * `c_beta`: `Real` (required, viscoplasticity coefficient) -* `PerzynaPlasticFlowRate` (NEML2) : - * `reference_stress`: `Real` (e.g., `100`) - * `exponent`: `Real` (e.g., `2`) -* `HEVPFlowRatePowerLawJ2` : - * `reference_flow_rate`: `Real` (default `0.001`) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-crystal-plasticity-advanced.md b/packages/akms/src/akms/_bundled/global_nodes/moose-crystal-plasticity-advanced.md deleted file mode 100644 index 4bd3aac..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-crystal-plasticity-advanced.md +++ /dev/null @@ -1,247 +0,0 @@ ---- -id: moose-crystal-plasticity-advanced -title: MOOSE Crystal Plasticity — Advanced Features -domain: constitutive -subdomain: algorithmic -tags: -- twinning -- phase-transformation -- polycrystal-homogenization -- voronoi -- grain-tracker -- RVE -- periodic-bc -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-stress-computation-chain - type: requires - weight: 0.7 - note: Part of the stress computation dispatch chain -- to: moose-crystal-plasticity - type: requires - weight: 0.9 - note: Extends base CP framework -- to: moose-nucleation-grain-growth - type: requires - weight: 0.5 - note: Polycrystal CP couples with grain growth -- to: cm-anisotropic-yield - type: implements - weight: 0.6 - note: Extends crystal plasticity with twinning and polycrystal features ---- - -# MOOSE Crystal Plasticity — Advanced Features - -Framework knowledge node covering 2 aspect(s) of Crystal Plasticity — Advanced Features. - -## Crystal plasticity twinning and phase transformation - -The MOOSE crystal plasticity module supports deformation twinning through the `CrystalPlasticityTwinningKalidindiUpdate` class, which implements a Kalidindi-based twinning propagation model for FCC and HCP materials . This module tracks the volume fraction of twinned regions and can be coupled with dislocation slip models . However, it does not explicitly support stress-induced phase transformations (TRIP implementations) or reorientation of the crystal lattice due to twinning . - -## Deformation Twinning - -### Classes & Methods - -* `CrystalPlasticityTwinningKalidindiUpdate` : A material model that computes plastic shear increment due to twinning based on Kalidindi's model . - * `CrystalPlasticityTwinningKalidindiUpdate::validParams()`: Defines the input parameters for the twinning model . - * `CrystalPlasticityTwinningKalidindiUpdate::initQpStatefulProperties()`: Initializes stateful material properties, including twin volume fractions and slip resistance . - * `CrystalPlasticityTwinningKalidindiUpdate::calculateSlipRate()`: Computes the plastic shear increment due to twinning using a power law constitutive model . - * `CrystalPlasticityTwinningKalidindiUpdate::calculateStateVariableEvolutionRateComponent()`: Calculates the rate of twin volume fraction on each twin system . - * `CrystalPlasticityTwinningKalidindiUpdate::calculateTwinVolumeFraction()`: Updates the twin volume fraction for each system and the total twin volume fraction . - * `CrystalPlasticityTwinningKalidindiUpdate::calculateTwinResistance()`: Calculates the twin propagation resistance based on coplanar and non-coplanar hardening coefficients . - -### Twin Systems: Definition - -Twin systems are defined similarly to slip systems by providing a `slip_sys_file_name` parameter, which specifies the crystallographic orientations for twinning . The `CrystalPlasticityTwinningKalidindiUpdate` class uses these definitions to calculate resolved shear stresses and plastic shear increments . - -### Volume Fraction Tracking for Twinned Regions - -The module tracks the volume fraction of twinned regions on each twin system and the total twin volume fraction . -The total twin volume fraction is stored in the material property `_total_twin_volume_fraction` , and individual twin system volume fractions are stored in `_twin_volume_fraction` . An upper limit for the total twin volume fraction can be set using the `upper_limit_twin_volume_fraction` parameter . - -### Reorientation of the Crystal Lattice Due to Twinning - -The current implementation of `CrystalPlasticityTwinningKalidindiUpdate` does not explicitly support reorientation of the crystal lattice due to twinning . The model focuses on the propagation of twins and their contribution to plastic deformation and hardening . - -### Transformation Plasticity (TRIP) Implementations - -The MOOSE crystal plasticity module, specifically `CrystalPlasticityTwinningKalidindiUpdate`, does not include implementations for stress-induced phase transformations (TRIP) . Its scope is limited to deformation twinning and dislocation slip . - -### Interaction Between Slip and Twin Systems — Latent Hardening Across Mechanisms - -The interaction between slip and twin systems is handled by modifying the plastic velocity gradient calculation . When both twinning and dislocation slip models are included, the plastic velocity gradient ($L^P$) is calculated as a weighted sum of contributions from both mechanisms : - -$$ -L^P = \left(1 - {f_{total}}_{(n-1)} \right) \sum_{\alpha}^{slip} \dot{\gamma}^{\alpha} S^{\alpha}_o + \sum_{\beta}^{twin} \dot{f}^{\beta}\gamma_{tw}S^{\beta}_o \quad (1) -$$ - -Here, $f_{total}$ is the total twin volume fraction, $\dot{\gamma}^{\alpha}$ is the plastic shear rate due to dislocation slip, $S^{\alpha}_o$ is the Schmid tensor for slip systems, $\dot{f}^{\beta}$ is the rate of twin volume fraction, and $S^{\beta}_o$ is the Schmid tensor for twinning systems . The total twin volume fraction from the previous timestep, $f_{total(n-1)}$, is used to couple the models . - -Latent hardening across mechanisms is implemented through the twin propagation resistance calculation, which considers different hardening coefficients for non-coplanar and coplanar twinning systems . - -$$ -\Delta g^{\beta} = \gamma_{tw} \left[ h_{nc}\left( f_{total} \right)^b \sum_{nc}^k \dot{f}^k + h_{cp}\left( f_{total} \right) \sum_{cp}^k \dot{f}^k \right] \quad (2) -$$ - -where $h_{nc}$ is the non-coplanar hardening coefficient, $b$ is the hardening exponent, and $h_{cp}$ is the coplanar hardening coefficient . - -### Parameters - -The `CrystalPlasticityTwinningKalidindiUpdate` class exposes several parameters for configuring the twinning model : - -* `initial_total_twin_volume_fraction = 0.0` (Real): Initial sum of twin volume fraction across all systems . -* `twin_reference_strain_rate = 1.0e-3` (Real): Reference strain rate ($\gamma_o$) for the power law . -* `twin_strain_rate_sensitivity_exponent = 0.05` (Real): Strain rate sensitivity exponent ($m$) . -* `characteristic_twin_shear = 1.0 / std::sqrt(2.0)` (Real): Characteristic shear of the twin ($\gamma_{tw}$) . -* `initial_twin_lattice_friction = 0.0` (Real): Initial lattice friction for twin propagation . -* `non_coplanar_coefficient_twin_hardening = 8000.0` (Real): Hardening coefficient for non-coplanar twin systems ($h_{nc}$) . -* `coplanar_coefficient_twin_hardening = 800.0` (Real): Hardening coefficient for coplanar twin systems ($h_{cp}$) . -* `non_coplanar_twin_hardening_exponent = 0.05` (Real): Hardening exponent for non-coplanar twin systems ($b$) . -* `upper_limit_twin_volume_fraction = 0.8` (Real): Maximum allowed total twin volume fraction ($f_{limit}$) . - -### MOOSE Input Syntax - -An example of how to configure the `CrystalPlasticityTwinningKalidindiUpdate` material model in a MOOSE input file is shown below : - -` ` `ini -[Materials] - [twin_only_xtalpl] - type = CrystalPlasticityTwinningKalidindiUpdate - number_slip_systems = 12 - slip_sys_file_name = 'fcc_input_twinning_systems.txt' - initial_twin_lattice_friction = 1.5 - upper_limit_twin_volume_fraction = 1e-7 - stol = 0.01 - print_state_variable_convergence_error_messages = true - [] -[] -` ` ` - -To couple twinning with dislocation slip, the `total_twin_volume_fraction` property from the twinning model must be provided to the slip model : - -` ` `ini -[Materials] - [slip_xtalpl] - type = CrystalPlasticityKalidindiUpdate - number_slip_systems = 12 - slip_sys_file_name = input_slip_sys.txt - total_twin_volume_fraction = 'twin_total_volume_fraction_twins' - [] -[] -` ` ` - -## Notes - -The `CrystalPlasticityTwinningKalidindiUpdate` model is based on the Kalidindi (2001) constitutive model . It does not allow for de-twinning - - -## Crystal plasticity polycrystal homogenization - -MOOSE handles polycrystal simulations, particularly in the context of crystal plasticity and phase-field grain growth, primarily through its `phase_field` and `solid_mechanics` modules. - -### 1. Full-field (each element = one orientation) vs. homogenization approaches - -The provided context does not explicitly detail the distinction between full-field (each element = one orientation) and homogenization approaches for polycrystal simulations in crystal plasticity. However, the presence of `ComputePolycrystalElasticityTensor` suggests a full-field approach where elasticity can vary per grain, which implies per element if grains are resolved at the element level. The `CrystalPlasticityStressUpdateBase` and `FiniteStrainCrystalPlasticity` classes in the `solid_mechanics` module indicate that crystal plasticity models are implemented at the material point level, which is consistent with a full-field approach where each quadrature point within an element can have its own crystal orientation and plastic response. - -### 2. `PolycrystalElasticDrivingForce` and grain boundary energy contributions - -The provided context does not contain information about a class named `PolycrystalElasticDrivingForce`. However, the `Grain Growth Model` documentation discusses grain boundary energy contributions within the phase-field framework. The free energy functional $F$ includes a term $\kappa \sum^N_i |\nabla \eta_i|^2$ , which represents the gradient energy related to grain boundaries. The parameter $\kappa$ is defined in terms of the grain boundary energy $\sigma$ and diffuse grain boundary width $w_{GB}$ as $\kappa = \frac{3}{4} \sigma w_{GB}$ . The `GBEvolution` material defines these model parameters. - -### 3. Voronoi tessellation: `PolycrystalVoronoi` for initial grain structure generation - -MOOSE uses the `PolycrystalVoronoi` UserObject to generate initial polycrystal grain structures using Voronoi tessellation . This UserObject can either generate random points as grain centroids or read them from a file . - -**Classes & Methods:** -* `PolycrystalVoronoi::validParams()`: Defines the input parameters for the `PolycrystalVoronoi` UserObject . -* `PolycrystalVoronoi::PolycrystalVoronoi(const InputParameters & parameters)`: Constructor for the `PolycrystalVoronoi` class, which initializes parameters like the number of grains, random seed, and interface width . -* `PolycrystalVoronoi::getGrainsBasedOnPoint(const Point & point, std::vector & grains) const`: This method determines the grain(s) associated with a given spatial point . It can use a KD-tree for faster searching . -* `PolycrystalVoronoi::precomputeGrainStructure()`: Overridden method to precompute the grain structure . -* `PolycrystalVoronoi::buildSearchTree()`: Builds a KD-tree to speed up grain searches . - -**Parameters:** -* `grain_num`: `unsigned int`, default `0`. Number of grains to be represented by order parameters . -* `rand_seed`: `unsigned int`, default `0`. The random seed for grain generation . -* `columnar_3D`: `bool`, default `false`. Specifies if the 3D microstructure is columnar in the z-direction . -* `use_kdtree`: `bool`, default `false`. Enables the use of a KD-tree for faster grain searches . -* `point_patch_size`: `unsigned int`, default `1`. How many nearest points the KDTree should return . -* `grain_patch_size`: `unsigned int`, default `10`. How many nearest grains the KDTree should return . -* `file_name`: `FileName`, default `""`. Path to a file containing grain centroids . -* `int_width`: `Real`, default `0.0`. Width of diffuse interfaces . - -**MOOSE Input Syntax:** -` ` `ini -[UserObjects] - [voronoi] - type = PolycrystalVoronoi - grain_num = 12 # Number of grains - coloring_algorithm = jp - rand_seed = 10 - # use_kdtree = true # Uncomment to enable KDTree - [] -[] - -[ICs] - [PolycrystalICs] - [PolycrystalColoringIC] - polycrystal_ic_uo = voronoi - [] - [] -[] -` ` ` - -### 4. Coupling with phase field grain growth: how do CP and grain evolution interact? - -The `phase_field` module provides capabilities for microstructure evolution, including grain tracking and phase transformations . The `Grain Growth Model` documentation describes the Allen-Cahn equation used for grain evolution. - -Coupling between crystal plasticity and grain evolution can occur through: -* **Material properties**: The `ComputePolycrystalElasticityTensor` material in the `phase_field` module computes an evolving elasticity tensor coupled to a grain growth phase field model. This implies that the elastic properties used in crystal plasticity calculations can be influenced by the evolving grain structure. -* **UserObjects**: `PolycrystalUserObjectBase` and its derivatives like `PolycrystalVoronoi` provide information about the grain structure (e.g., grain IDs, centroids) that can be used by other modules. -* **Order Parameters**: The phase field model uses order parameters ($\eta_i$) to represent different grains . These order parameters can influence material properties, which in turn affect the crystal plasticity response. - -### 5. RVE (Representative Volume Element) computations: periodic BCs, volume averaging of stress/strain - -The use of periodic boundary conditions (BCs) is mentioned in the context of `PolycrystalVoronoiIC_periodic.i` and `PolycrystalHex` , indicating support for RVE computations. For example, `PolycrystalHex` explicitly checks for periodic BCs . The `PolycrystalUserObjectBase` also checks for consistent periodicity across coupled variables . - -The provided context does not explicitly detail volume averaging of stress/strain for RVE computations, but it is a common post-processing step in such simulations. - -### 6. Performance: how does MOOSE parallelize polycrystal CP simulations? - -MOOSE is designed for parallel execution, and this extends to polycrystal simulations. The `Physics Modules` wiki page mentions that module objects requiring parallel communication should use libMesh/PETSc communicator patterns . - -Specifically for `PolycrystalVoronoi`, the `use_kdtree` parameter is available to speed up grain searches, especially for a large number of grains . The `KDTree` is built a-priori to optimize the search time for nearest points and neighboring grains . - -The `distributed_poly_ic.i` test input file explicitly sets `parallel_type = distributed` for the mesh, indicating that polycrystal initial condition generation can be run in parallel. - -## Classes & Methods: - -* `PolycrystalVoronoi::validParams()`: Defines input parameters for Voronoi tessellation . -* `PolycrystalVoronoi::getGrainsBasedOnPoint()`: Determines grain(s) associated with a spatial point . -* `PolycrystalVoronoi::buildSearchTree()`: Constructs a KD-tree for efficient grain searching . -* `PolycrystalColoringIC::value()`: Returns the order parameter value for a given point based on the polycrystal user object . -* `PolycrystalUserObjectBase::initialSetup()`: Checks for consistent periodicity across coupled variables . -* `ComputePolycrystalElasticityTensor::computeQpElasticityTensor()`: Computes the elasticity tensor at a quadrature point, coupled to grain growth . -* `CrystalPlasticityStressUpdateBase::getSlipSystems()`: Reads and normalizes slip system vectors from a file . -* `FiniteStrainUObasedCP`: Material class for user-object-based finite strain crystal plasticity . - -## Equations: - -The grain growth model uses the Allen-Cahn equation for the evolution of each grain's order parameter: -$$ -\frac{\partial \eta_i}{\partial t} = - L \frac{\delta F}{\delta \eta_i} \quad (1) -$$ -where $F$ is the free energy functional, $L$ is the order parameter mobility, and $\delta$ represents a variational derivative. The free energy functional is given by: -$$ -F = \int_V f_{loc}(\eta_0, \eta_1, \ldots, \eta_N) + f_{add} (\eta_0, \eta_1, \ldots, \eta_N) + \kappa \sum^N_i |\nabla \eta_i|^2 \quad (2) -$$ - -Wiki pages you might want to explore: -- [Physics Modules (idaholab/moose)](https://deepwiki.com/idaholab/moose#5) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-crystal-plasticity.md b/packages/akms/src/akms/_bundled/global_nodes/moose-crystal-plasticity.md deleted file mode 100644 index eae84bb..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-crystal-plasticity.md +++ /dev/null @@ -1,411 +0,0 @@ ---- -id: moose-crystal-plasticity -title: MOOSE Crystal Plasticity — Constitutive Framework -domain: constitutive -subdomain: algorithmic -tags: -- crystal-plasticity -- slip-systems -- hardening -- euler-angles -- polycrystal -- multiplicative-decomposition -- resolved-shear-stress -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: large -reading_priority: full -akms_schema: v2 -edges: -- to: moose-stress-computation-chain - type: requires - weight: 0.7 - note: Part of the stress computation dispatch chain -- to: moose-strain-formulations - type: requires - weight: 0.8 - note: CP uses finite strain kinematics -- to: cm-anisotropic-yield - type: implements - weight: 0.8 - note: Implements crystal plasticity with slip-system-level flow rules -- to: cm-kinematics-tl - type: implements - weight: 0.7 - note: Uses multiplicative decomposition F=Fe·Fp in finite strain ---- - -# MOOSE Crystal Plasticity — Constitutive Framework - -Framework knowledge node covering 3 aspect(s) of Crystal Plasticity — Constitutive Framework. - -## Crystal plasticity stress update algorithm - -The MOOSE framework implements crystal plasticity primarily through the `CrystalPlasticityStressUpdateBase` class and its derived classes, such as `CrystalPlasticityKalidindiUpdate` and `ComputeMultipleCrystalPlasticityStress` . The implementation uses a multiplicative decomposition of the deformation gradient and an iterative Newton-Raphson approach to update the stress state and internal variables . - -## Multiplicative Decomposition $F = F^e \cdot F^p$ - -The crystal plasticity models in MOOSE utilize the multiplicative decomposition of the total deformation gradient $F$ into an elastic component $F^e$ and a plastic component $F^p$ . This decomposition is fundamental to the stress update algorithm, where the plastic deformation gradient `_plastic_deformation_gradient` is a stateful material property that is evolved over time . - -## `CrystalPlasticityStressUpdateBase` — Stress Update Algorithm - -The `CrystalPlasticityStressUpdateBase` class provides the foundational structure for crystal plasticity stress updates . Derived classes implement the specific constitutive laws. The stress update involves an iterative process to converge the stress state and internal variables . - -### Algorithm Steps - -The overall stress update is handled by `ComputeMultipleCrystalPlasticityStress::computeQpStress()` , which calls `solveQp()` to perform the iterative solution. - -#### a. Trial Elastic Deformation Gradient: $F^e_{trial} = F \cdot (F^p_{old})^{-1}$ - -The trial elastic deformation gradient is implicitly calculated within the stress update. The `_plastic_deformation_gradient_old` and `_deformation_gradient` (current total deformation gradient) are used to compute the elastic response . - -#### b. Resolved Shear Stress on each Slip System: $\tau^\alpha = \Sigma_{ij} (S^e_{ij} \cdot s^\alpha_i \cdot m^\alpha_j)$ - -The resolved shear stress $\tau^\alpha$ on each slip system is calculated by the `CrystalPlasticityStressUpdateBase::calculateShearStress()` method . This method takes the PK2 stress and other deformation gradient components to compute `_tau`, which stores the applied shear stress for each slip system . The Schmid tensor, which involves the slip direction `_slip_direction` and slip plane normal `_slip_plane_normal`, is computed by `calculateSchmidTensor()` . - -#### c. Flow Rule: $\dot{\gamma}^\alpha = \dot{\gamma}_0 \cdot |\tau^\alpha/g^\alpha|^n \cdot \text{sign}(\tau^\alpha)$ (power law) - -A common power law flow rule is used in several crystal plasticity models, such as `CrystalPlasticityKalidindiUpdate` and `FiniteStrainCrystalPlasticity` . The parameters involved are: -* $\dot{\gamma}_0$: Reference slip rate . -* $\tau^\alpha$: Applied shear stress on slip system $\alpha$ . -* $g^\alpha$: Slip system strength or resistance to slip . -* $n$ (or $1/m$): Strain rate sensitivity exponent . - -The `calculateSlipRate()` virtual method in `CrystalPlasticityStressUpdateBase` is responsible for computing the slip increment based on the constitutive model defined in child classes . - -#### d. Plastic Velocity Gradient: $L^p = \Sigma^\alpha \dot{\gamma}^\alpha \cdot s^\alpha \otimes m^\alpha$ - -The plastic velocity gradient is constructed from the sum of contributions from each slip system. The `_flow_direction` property, which is a `std::vector`, stores the Schmid tensors ($s^\alpha \otimes m^\alpha$) for each slip system . The slip rates `_slip_increment` are calculated and used in conjunction with `_flow_direction` to update the plastic deformation . - -#### e. Update $F^p$ via exponential map or forward Euler - -The update of $F^p$ is handled internally within the stress update routines. While the prompt mentions exponential map or forward Euler, the documentation for `ComputeMultipleCrystalPlasticityStress` states that "Backward Euler integration rule is used for the rate equations" . - -#### f. Newton Iteration to converge the stress state - -The stress state is converged using a Newton-Raphson iteration. The `ComputeMultipleCrystalPlasticityStress` class explicitly mentions solving the "PK2 stress residual equation using Newton - Raphson" . The `calculateResidualAndJacobian()` method is called to compute the residual `_residual_tensor` and Jacobian `_jacobian` . The `solveStress()` method performs the actual stress update . - -## Convergence Criterion for the Crystal Plasticity Inner Loop - -The convergence of the crystal plasticity inner loop, which involves the stress state and internal variables, is controlled by several tolerances: -* `_rtol`: Stress residual equation relative tolerance . -* `_abs_tol`: Stress residual equation absolute tolerance . -* `_rel_state_var_tol` (`stol`): Constitutive internal state variable relative change tolerance . -* `_slip_incr_tol`: Maximum allowable slip in an increment for each individual constitutive model . -* `_resistance_tol`: Constitutive slip system resistance relative residual tolerance . -* `_zero_tol`: Tolerance for residual check when variable value is zero . - -The `areConstitutiveStateVariablesConverged()` virtual method in `CrystalPlasticityStressUpdateBase` is used to determine if all state variables have converged . - -## Slip System Geometries (FCC, BCC, HCP) - -Slip system geometries are defined by reading data from a file specified by `slip_sys_file_name` . The `CrystalPlasticityStressUpdateBase::getSlipSystems()` method handles reading and processing this data . - -* **Crystal Lattice Type**: The `crystal_lattice_type` parameter, an `MooseEnum`, specifies the lattice type (BCC, FCC, HCP) . -* **Miller Indices / Miller-Bravais**: For BCC and FCC crystals, slip plane normals and directions are read directly from the file and scaled by `_unit_cell_dimension` . For HCP crystals, a transformation from Miller-Bravais 4-index notation to a 3-index Cartesian representation is performed by `transformHexagonalMillerBravaisSlipSystems()` . This transformation also includes checks to ensure that the Miller-Bravais indices for the basal plane sum to zero . -* **Unit Cell Dimensions**: The `unit_cell_dimension` parameter allows specifying the dimensions of the unit cell, which are used in scaling the slip system vectors . - -### Classes & Methods - -* `CrystalPlasticityStressUpdateBase::validParams()`: Defines input parameters common to all crystal plasticity stress update materials . -* `CrystalPlasticityStressUpdateBase::getSlipSystems()`: Reads slip system data from a file and normalizes vectors . -* `CrystalPlasticityStressUpdateBase::transformHexagonalMillerBravaisSlipSystems()`: Transforms HCP Miller-Bravais indices to Cartesian coordinates . -* `CrystalPlasticityStressUpdateBase::calculateShearStress()`: Computes the resolved shear stress for each slip system . -* `CrystalPlasticityStressUpdateBase::calculateSlipRate()`: Virtual method to calculate the slip increment based on the constitutive model . -* `CrystalPlasticityStressUpdateBase::areConstitutiveStateVariablesConver - - -## Crystal plasticity hardening laws - -The MOOSE framework implements several hardening laws for crystal plasticity, primarily through the `CrystalPlasticityKalidindiUpdate` class and the `CrystalPlasticityStateVarRateComponentVoce` UserObject . These implementations handle self and latent hardening, and store history variables like slip resistance as material properties . - -## Hardening Laws Implemented - -### Kalidindi Hardening Model -The `CrystalPlasticityKalidindiUpdate` class implements the self and latent hardening crystal plasticity model developed by Kalidindi et al. (1992) . - -**Equations:** -The slip rate is given by a power law relationship: -$$ -\dot{\gamma}^{\alpha} = \dot{\gamma}_o \left| \frac{\tau^{\alpha}}{g^{\alpha}} \right|^{1/m} sign \left( \tau^{\alpha} \right) \quad (1) -$$ -where $\dot{\gamma}_o$ is a reference slip rate, $\tau^{\alpha}$ is the applied shear stress, $g^{\alpha}$ is the slip system strength (resistance to slip), and $m$ is the strain rate sensitivity exponent . - -The evolution of slip system strength (resistance) is given by: -$$ -g^{\alpha} = g_o + \Delta \gamma^{\alpha} q^{\alpha \beta} h_o \left| 1 - \frac{g^{\alpha}}{g_{sat}} \right|^a sign \left( 1 - \frac{g^{\alpha}}{g_{sat}} \right) \quad (2) -$$ -where $q^{\alpha \beta}$ is the hardening coefficient matrix, $h_o$ is an initial hardening term, $g_{sat}$ is the saturated hardening value, and $a$ is the hardening exponent . - -The hardening coefficient matrix $q^{\alpha \beta}$ for an FCC system is defined as: -$$ -q^{\alpha \beta} = \begin{Bmatrix} - 1.0 & q & q & q \\ - q & 1.0 & q & q \\ - q & q & 1.0 & q \\ - q & q & q & 1.0 - \end{Bmatrix} \quad (3) -$$ -where $q$ is a constant value of latent hardening among non-coplanar slip systems . - -**Classes & Methods:** -* `CrystalPlasticityKalidindiUpdate::validParams()`: Defines the input parameters for the Kalidindi hardening model . -* `CrystalPlasticityKalidindiUpdate::initQpStatefulProperties()`: Initializes stateful properties like slip system resistances . -* `CrystalPlasticityKalidindiUpdate::setInitialConstitutiveVariableValues()`: Sets initial values for constitutive variables . -* `CrystalPlasticityKalidindiUpdate::calculateSlipRate()`: Calculates the slip rate for each slip system . -* `CrystalPlasticityKalidindiUpdate::calculateStateVariableEvolutionRateComponent()`: Calculates the slip system resistance increment based on Kalidindi et al. (1992) . -* `CrystalPlasticityKalidindiUpdate::updateStateVariables()`: Finalizes the values of state variables after convergence . - -**Parameters:** -The `CrystalPlasticityKalidindiUpdate` class uses the following parameters : -* `r`: Latent hardening coefficient (default: 1.0) -* `h`: Hardening constant (default: 541.5) -* `t_sat`: Saturated slip system strength (default: 109.8) -* `gss_a`: Coefficient for hardening (default: 2.5) -* `ao`: Slip rate coefficient (default: 0.001) -* `xm`: Exponent for slip rate (default: 0.1) -* `gss_initial`: Initial lattice friction strength (default: 60.8) -* `total_twin_volume_fraction`: Name of the material property for total twin volume fraction, if twinning is considered . - -### Voce Hardening Model -The `CrystalPlasticityStateVarRateComponentVoce` UserObject implements a phenomenological Voce constitutive model for state variable evolution . - -**Equations:** -The hardening rate `hb(i)` for a slip system `i` is calculated as: -$$ -hb(i) = h_0 \left| 1 - \frac{g^{\alpha} - \tau_0}{\tau_{sat} - \tau_0} \right|^{hardening\_exponent} \text{sign}\left(1 - \frac{g^{\alpha} - \tau_0}{\tau_{sat} - \tau_0}\right) \quad (4) -$$ -where $h_0$ is an initial hardening constant, $\tau_0$ is the initial critical resolved shear stress, $\tau_{sat}$ is the saturation resolved shear stress, and $hardening\_exponent$ is the hardening exponent . -The evolution rate of the state variable `val[i]` is then calculated by summing contributions from all slip systems `j`, considering self and latent hardening coefficients `q_ab`: -$$ -val[i] += |\dot{\gamma}_{j}| \cdot q_{ab} \cdot hb(j) \quad (5) -$$ - -**Classes & Methods:** -* `CrystalPlasticityStateVarRateComponentVoce::validParams()`: Defines input parameters for the Voce hardening model . -* `CrystalPlasticityStateVarRateComponentVoce::calcStateVariableEvolutionRateComponent()`: Computes the slip system hardening rate . -* `CrystalPlasticityStateVarRateComponentVoce::getHardeningCoefficient()`: Retrieves the appropriate self/latent hardening coefficient . - -**Parameters:** -The `CrystalPlasticityStateVarRateComponentVoce` class uses the following parameters : -* `uo_slip_rate_name`: Name of the slip rate property. -* `uo_state_var_name`: Name of the state variable property. -* `crystal_lattice_type`: Type of crystal lattice structure (e.g., "FCC", "BCC"). -* `groups`: Defines slip system groups (e.g., '0 12 24 48'). -* `h0_group_values`: `h0` hardening constant for each group. -* `tau0_group_values`: Initial critical resolved shear stress for each group. -* `tauSat_group_values`: Saturation resolved shear stress for each group. -* `hardeningExponent_group_values`: Hardening exponent for each group. -* `selfHardening_group_values`: Self-hardening coefficient `q_aa` for each group. -* `coplanarHardening_group_values`: Coplanar latent hardening coefficient `q_ab` for each group. -* `GroupGroup_Hardening_group_values`: Group-to-group latent hardening coefficient `q_ab` (N x N matrix). - -**MOOSE Input Syntax Example:** -` ` `ini -[UserObjects] - [./state_var_evol_rate_comp_voce] - type = CrystalPlasticityStateVarRateComponentVoce - variable_size = 48 - crystal_lattice_type = 'BCC' - groups = '0 12 24 48' - h0_group_values = '1 2 3' - tau0_group_values = '50 51 52' - tauSat_group_values = '70 81 92' - hardeningExponent_group_values = '1 2 3' - selfHardening_group_values ='4 5 6' - coplanarHardening_group_values='7 8 9' - GroupGroup_Hardening_group_values = '10 20 30 - 40 50 60 - 70 80 90' - uo_slip_rate_name = slip_rate_gss - uo_state_var_name = state_var_gss - [../] -[] -` ` ` - -### Beyerlein Hardening Model (HCP) -The `CrystalPlasticityHCPDislocationSlipBeyerleinUpdate` class implements a constitutive model for the glide and evolution of forest dislocations within an HCP crystal lattice . This model considers contributions from initial lattice friction, Hall-Petch type hardening, forest dislocations, and substructure density . - -**Equations:** -The total slip resistance $g^{\alpha}$ is the sum of four terms: -$$ -g^{\alpha} = g^{\alpha}_o + g^{\alpha}_{HP} + g^{\alpha}_{forest} + g^{\alpha}_{sub} \quad (6) -$$ -where $g^{\alpha}_o$ is initial lattice friction, $g^{\alpha}_{HP}$ is Hall-Petch hardening, $g^{\alpha}_{forest}$ is forest dislocation hardening, and $g^{\alpha}_{sub}$ is substructure hardening . - -Hall-Petch hardening: -$$ -g^{\alpha}_{HP} = HP^{\alpha}\mu^{\alpha} \sqrt{\frac{b^{\alpha}}{d_g}} \quad (7) -$$ - - -## Crystal plasticity slip systems and orientation - -MOOSE handles crystallographic orientations and slip systems primarily within the `solid_mechanics` module, particularly for crystal plasticity models . It supports defining slip systems from files, reading Euler angles (Bunge convention), applying crystal-to-sample rotations, and integrating with EBSD data for polycrystal orientations . - -## Slip System Definition Files - -Slip systems are defined in external text files, which are then read by MOOSE . The `CrystalPlasticityStressUpdateBase` class handles reading these files . - -### Format for Specifying {hkl} Systems - -The slip system files typically contain the slip plane normal and slip direction vectors . For HCP crystals, a 4-index Miller-Bravais notation can be transformed into a 3-index Cartesian representation . - -**Parameters:** -* `slip_sys_file_name` = "path/to/file.txt" (type: `FileName`, required): Name of the file containing slip systems, with the slip plane normal given before the slip plane direction . -* `number_slip_systems` (type: `unsigned int`, required): The total number of possible active slip systems . -* `crystal_lattice_type` (type: `MooseEnum`, default: "FCC"): Specifies the crystal lattice type (BCC, FCC, HCP) . -* `unit_cell_dimension` (type: `std::vector`, default: `{1.0, 1.0, 1.0}`): Dimensions of the unit cell, used for computing slip systems . - -**Code Snippets:** -The `getSlipSystems()` method in `CrystalPlasticityStressUpdateBase` reads and normalizes the slip system vectors . For HCP crystals, `transformHexagonalMillerBravaisSlipSystems()` performs the coordinate transformation . - -` ` `cpp -void -CrystalPlasticityStressUpdateBase::getSlipSystems() -{ - bool orthonormal_error = false; - - // read in the slip system data from auxiliary text file - MooseUtils::DelimitedFileReader _reader(_slip_sys_file_name); - _reader.setFormatFlag(MooseUtils::DelimitedFileReader::FormatFlag::ROWS); - _reader.read(); - - // check the size of the input - if (_reader.getData().size() != _number_slip_systems) - paramError( - "number_slip_systems", - "The number of rows in the slip system file should match the number of slip system."); - - for (const auto i : make_range(_number_slip_systems)) - { - // initialize to zero - _slip_direction[i].zero(); - _slip_plane_normal[i].zero(); - } - - if (_crystal_lattice_type == CrystalLatticeType::HCP) - transformHexagonalMillerBravaisSlipSystems(_reader); - else if (_crystal_lattice_type == CrystalLatticeType::BCC || - _crystal_lattice_type == CrystalLatticeType::FCC) - { - for (const auto i : make_range(_number_slip_systems)) - { - // directly grab the raw data and scale it by the unit cell dimension - for (const auto j : index_range(_reader.getData(i))) - { - if (j < LIBMESH_DIM) - _slip_plane_normal[i](j) = _reader.getData(i)[j] / _unit_cell_dimension[j]; - else - _slip_direction[i](j - LIBMESH_DIM) = - _reader.getData(i)[j] * _unit_cell_dimension[j - LIBMESH_DIM]; - } - } - } - - for (const auto i : make_range(_number_slip_systems)) - { - // normalize - _slip_plane_normal[i] /= _slip_plane_normal[i].norm(); - _slip_direction[i] /= _slip_direction[i].norm(); - - if (_crystal_lattice_type != CrystalLatticeType::HCP) - { - const auto magnitude = _slip_plane_normal[i] * _slip_direction[i]; - if (std::abs(magnitude) > libMesh::TOLERANCE) - { - orthonormal_error = true; - break; - } - } - } - - if (orthonormal_error) - mooseError("CrystalPlasticityStressUpdateBase Error: The slip system file contains a slip " - "direction and plane normal pair that are not orthonormal in the Cartesian " - "coordinate system."); -} -` ` ` - -## Euler Angle Input and Rotation Tensors - -MOOSE uses Euler angles to define crystallographic orientations, primarily following the Bunge convention . - -### Euler Angle Input: Bunge Convention - -The `ComputeElasticityTensorCP` class accepts Bunge Euler angles as input . These can be provided directly in the input file, read from a `PropertyReadFile` user object, or coupled from other variables . - -**Parameters:** -* `euler_angle_1`, `euler_angle_2`, `euler_angle_3` (type: `Real`): Individual Euler angles . -* `read_prop_user_object` (type: `UserObjectName`): A `PropertyReadFile` user object to read Euler angles per element . -* `euler_angle_variables` (type: `std::vector`): Coupled variables providing Euler angles . - -### Rotation Tensors: Crystal-to-Sample Rotation - -The `RotationTensor` class is used to manage and apply rotations . The `ComputeElasticityTensorCP` material generates a "passive" rotation matrix from the Euler angles or a user-supplied rotation matrix . This matrix rotates the crystal slip system direction and plane normals into the user-specified orientation . - -**Equations:** -The rotation matrix $R$ can be directly provided or constructed from Euler angles. The documentation provides an example of a rotation matrix : -$$ -R = \begin{bmatrix} - \frac{\sqrt{2}}{2} & \frac{\sqrt{6}}{6} & \frac{\sqrt{3}}{3} \\ - -\frac{\sqrt{2}}{2} & \frac{\sqrt{6}}{6} & \frac{\sqrt{3}}{3} \\ - 0 & -\frac{\sqrt{6}}{3} & \frac{\sqrt{3}}{3} - \end{bmatrix} -$$ - -This matrix is used for a "passive" rotation, converting directions from the sample frame to the crystal frame . - -**Classes & Methods:** -* `ComputeElasticityTensorCP::assignEulerAngles()`: Assigns Euler angles from various sources (input file, `PropertyReadFile`, coupled variables) to a material property . -* `ComputeElasticityTensorCP::computeQpElasticityTensor()`: Computes the elasticity tensor, applying the crystal rotation matrix . -* `CrystalPlasticityStressUpdateBase::calculateSchmidTensor()`: Rotates slip system plane normal and direction vectors into the local crystal lattice orientation using the crystal rotation tensor . - -## GrainTracker and Polycrystal - -The `phase_field` module provides tools for managing polycrystal structures and assigning orientations to grains . - -### Assigning Orientations to Grains in a Polycrystal - -The `PolycrystalUserObjectBase` class serves as a base for creating polycrystal initial conditions and discovering grain structures . Derived classes like `PolycrystalEBSD` can reconstruct grain structures from EBSD data . - -**Classes & Methods:** -* `PolycrystalUserObjectBase::getGrainsBasedOnPoint()`: Retrieves active grain IDs based on a point in the mesh . -* `PolycrystalUserObjectBase::getNumGrains()`: Returns the number of grains in the polycrystal structure . -* `PolycrystalEBSD`: A user object for setting up a polycrystal structure from an EBSD Datafile . It uses an `EBSDReader` to get data for specific points . - -## EBSD Data Integration - -MOOSE can integrate experimental orientation maps through the `EBSDReader` and `PolycrystalEBSD` classes . - -### Reading Experimental Orientation Maps - -The `EBSDReader` user object is responsible for reading EBSD data . The `PolycrystalEBSD` class then uses this reader to assign grain IDs and phase information based on spatial points . - -**MOOSE Input Syntax:** -` ` `ini -[UserObjects] - [ebsd_reader] - type = EBSDReader - [] - [ebsd] - type = PolycrystalEBSD - coloring_algorithm = bt - ebsd_reader = ebsd_reader - enable_var_coloring = true - [] -[] -` ` ` - -This input block defines an `EBSDReader` named `ebsd_reader` and a `PolycrystalEBSD` object named `ebsd` that uses the reader to set up the polycrystal structure . - -## Texture Evolution - -MOOSE can track orientation changes during deformation, particularly through the `EulerAngleUpdater` class - -Wiki pages you might want to explore: -- [Physics Modules (idaholab/moose)](https://deepwiki.com/idaholab/moose#5) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-derivative-parsed-material.md b/packages/akms/src/akms/_bundled/global_nodes/moose-derivative-parsed-material.md deleted file mode 100644 index ce478b6..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-derivative-parsed-material.md +++ /dev/null @@ -1,407 +0,0 @@ ---- -id: moose-derivative-parsed-material -title: MOOSE Phase Field Energy Parsing — DerivativeParsedMaterial -domain: phase-field -subdomain: algorithmic -tags: -- free-energy -- parsed-material -- symbolic-differentiation -- fparser -- derivative-material-interface -- CALPHAD -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: cm-phase-field-fracture - type: implements - weight: 0.6 - note: DerivativeParsedMaterial is the core free energy engine for all PF models ---- - -# MOOSE Phase Field Energy Parsing — DerivativeParsedMaterial - -Framework knowledge node covering 2 aspect(s) of Phase Field Energy Parsing — DerivativeParsedMaterial. - -## Free energy parsing system - -The MOOSE framework provides a robust system for parsing free energy expressions and automatically computing their derivatives, primarily through the `DerivativeParsedMaterial` class . This system leverages the `fparser` library for symbolic differentiation and allows for flexible definition of expressions, material properties, and coupled variables . - -## Classes & Methods - -* `DerivativeParsedMaterial` : A material class that evaluates a parsed function and automatically provides its derivatives. -* `DerivativeParsedMaterialHelperTempl::functionsPostParse()` : This method sets up variables and initiates the derivative generation process after the primary function has been parsed. -* `DerivativeParsedMaterialHelperTempl::assembleDerivatives()` : Handles the assembly of the computed derivatives. -* `FunctionMaterialPropertyDescriptor` : Parses and describes material properties, including their dependencies and derivation state. -* `DerivativeSumMaterial` : A meta-material class designed to combine multiple derivative materials, effectively summing up various free energy contributions. - -## `DerivativeParsedMaterial` and Automatic Differentiation - -The `DerivativeParsedMaterial` class automatically computes derivatives of a user-defined string expression . It achieves this by using the `fparser` library, specifically `libmesh/fparser_ad.hh` , which provides symbolic differentiation capabilities. When you define an `expression` in your input file, `DerivativeParsedMaterial` parses this expression and then, based on the `derivative_order` parameter, generates the required first, second, and potentially third-order derivatives . - -For example, if you provide an expression $f(\eta, c)$, the system can compute $\frac{\partial f}{\partial \eta}$, $\frac{\partial^2 f}{\partial \eta^2}$, $\frac{\partial^2 f}{\partial \eta \partial c}$, and so on . The `functionsPostParse()` method in `DerivativeParsedMaterialHelperTempl` is responsible for setting up the symbols and then triggering the derivative generation . - -## `FunctionParserBase` / `fparser` Backend - -The symbolic differentiation library used is `fparser`, specifically the `libmesh/fparser_ad.hh` header . This library allows MOOSE to parse mathematical expressions provided as strings and then symbolically differentiate them to obtain the required derivatives. - -## Referencing Material Property Names - -Material property names are referenced within parsed expressions using the `material_property_names` parameter . The `FunctionMaterialPropertyDescriptor` class is used to parse these names and understand their dependencies . - -The syntax for `material_property_names` is flexible: -* `F`: A material property `F` with no declared variable dependencies. -* `F(c,phi)`: A material property `F` dependent on variables `c` and `phi`. -* `d3x:=D[x(a,b),a,a,b]`: Defines a third derivative $\frac{\partial^3x}{\partial^2a\partial b}$ of material property `x` and assigns it the name `d3x` for use in the expression. -* `dF:=D[F,c]`: Derivative of `F` with respect to `c`. -* `F_old:=Old[F]` or `F_older:=Older[F]`: Accesses previous time step values of `F`. - - - -## Coupling Between Parsed Materials - -One `DerivativeParsedMaterial` can reference another by listing its output property name in its `material_property_names` parameter . For example, in the `GrandPotentialMultiphase.i` test, `omegab` references `Vm`, `kb`, and `cbeq`, which could be properties provided by other materials . The system automatically pulls in the necessary derivatives of these coupled material properties when constructing the derivatives of the parsed function . - -## `DerivativeSumMaterial` - -The `DerivativeSumMaterial` class is designed to combine multiple free energy contributions . It takes a list of material names via the `sum_materials` parameter and sums their contributions, potentially with prefactors and a constant term . - -### Parameters -* `sum_materials` (vector of strings): Base names of the parsed sum material properties . -* `coupled_variables` (vector of strings): Names of variables being summed . -* `prefactor` (vector of Reals, default: `{}`): Prefactor to multiply each sum term with . -* `constant` (Real, default: `0.0`): Constant to be added to the prefactor multiplied sum . - -## Performance: JIT-compilation and Caching - -The parsed expressions can be JIT-compiled for performance . The `enable_jit` parameter controls this behavior . Derivatives are also cached internally to avoid redundant computations. - -## Derivative Depth - -The `DerivativeParsedMaterial` can automatically compute derivatives up to the third order . The maximum order is controlled by the `derivative_order` parameter . Only required derivatives are evaluated . - -### Parameters -* `derivative_order` (unsigned int, default: `3`): Maximum order of derivatives to be taken . - -## `coupled_variables` Parameter - -The `coupled_variables` parameter maps variable names to symbols in the expression . These are the primary variables with respect to which derivatives are always taken . - -### Parameters -* `coupled_variables` (vector of strings): Vector of names of variables used in the parsed function . - -## Example Usage Pattern - -Here's an example of a free energy expression using `DerivativeParsedMaterial` from a MOOSE input file : - -` ` `ini -[Materials] - [local_energy] - type = DerivativeParsedMaterial - block = 0 - f_name = f_loc - args = c - constant_names = 'A B C D E F G eV_J d' - constant_expressions = '-2.446831e+04 -2.827533e+04 4.167994e+03 7.052907e+03 - 1.208993e+04 2.568625e+03 -2.354293e+03 - 6.24150934e+18 1e-27' - function = 'eV_J*d*(A*c+B*(1-c)+C*c*log(c)+D*(1-c)*log(1-c)+ - E*c*(1-c)+F*c*(1-c)*(2*c-1)+G*c*(1-c)*(2*c-1)^2)' - [] -[] -` ` ` - - -In this example: -* `type = DerivativeParsedMaterial` specifies the material class . -* `f_name = f_loc` gives a name to the free energy function . -* `args = c` defines `c` as a coupled variable (though `coupled_variables` is the more explicit parameter) . -* `constant_names` and `constant_expressions` define constants used in the expression . -* `function` (or `expression`) contains the free energy formula . - -## Relationships - -` ` `mermaid -classDiagram - class MooseObject - class Material - class ParsedMaterialBase - class ParsedMaterialHelper - class DerivativeParsedMaterialHelper - class DerivativeParsedMaterial - class DerivativeSumMaterial - class FunctionMaterialPropertyDescriptor - class DerivativeMaterialPropertyNameInterface - - MooseObject <|-- Material - Material <|-- ParsedMaterialBase - ParsedMaterialBase <|-- ParsedMaterialHelper - ParsedMaterialHelper <|-- DerivativeParsedMaterialHelper - DerivativeParsedMaterialHelper <|-- DerivativeParsedMaterial - Material <|-- DerivativeSumMaterial - - DerivativeMaterialPropertyNameInterface <|-- FunctionMaterialPropertyDescriptor - - DerivativeParsedMaterialHelper "1" *-- "1" FunctionMaterialPropertyDescriptor : uses - DerivativeParsedMaterialHelper "1" *-- "1" libmesh::fparser_ad : uses -` ` ` - -## Notes - -The `ParsedMaterialBase` class provides the fundamental parsing capabilities for expressions, constants, and material properties . `DerivativeParsedMaterial` extends this by adding automatic differentiation . The `additional_derivative_symbols` parameter allows specifying extra symbols (beyond coupled variables) for which derivatives should be computed . The `DerivativeFunctionMaterialBase` is a more general base class for materials that compute functions and their derivatives, which `DerivativeParsedMaterial` ultimately builds upon . - - -## Custom free energy materials without parsing - -MOOSE handles coded (C++) free energy materials through the `DerivativeMaterialInterface` and `DerivativeFunctionMaterialBase` classes, which allow you to define a free energy function and its derivatives. Kernels like `AllenCahn` and `SplitCHParsed` then consume these registered derivatives. - -## Classes & Methods - -### `DerivativeMaterialInterface` -The `DerivativeMaterialInterface` class is a veneer that provides methods for declaring and retrieving derivative material properties. - -### `DerivativeFunctionMaterialBase` -The `DerivativeFunctionMaterialBase` class is a base class for materials that compute a function and its derivatives. - -#### Methods to Implement in a Custom Material -When implementing a custom material that inherits from `DerivativeFunctionMaterialBase`, you must override the following methods to define your free energy function and its derivatives: -* `computeF()`: Overridden to provide the free energy function. -* `computeDF(unsigned int arg)`: Overridden to calculate the first derivatives. -* `computeD2F(unsigned int arg1, unsigned int arg2)`: Overridden to calculate the second derivatives. -* `computeD3F(unsigned int, unsigned int, unsigned int)`: Optionally overridden to calculate the third derivatives. - -### `DerivativeMaterialPropertyNameInterface` -This interface provides helper functions to generate material property names for arbitrary derivatives. - -#### Naming Convention for Derivative Properties -The naming convention for derivative properties is handled by helper functions in `DerivativeMaterialPropertyNameInterface`. -* `derivativePropertyNameFirst(const MaterialPropertyName & base, const SymbolName & c1)`: Generates the name for the first derivative, e.g., `d{base}/d{c1}`. -* `derivativePropertyNameSecond(const MaterialPropertyName & base, const SymbolName & c1, const SymbolName & c2)`: Generates the name for the second derivative, e.g., `d2{base}/d{c1}d{c2}`. -* `derivativePropertyNameThird(const MaterialPropertyName & base, const SymbolName & c1, const SymbolName & c2, const SymbolName & c3)`: Generates the name for the third derivative. - -### `DerivativeMaterialInterface::getMaterialPropertyDerivative()` -This method is used to retrieve derivative material properties. It has several overloads to handle different ways of specifying the variables with respect to which the derivative is taken. For example, you can retrieve a derivative by providing the base property name and the names of the coupled variables, or by using indices into the `_coupled_standard_moose_vars` vector. - -` ` `cpp -template -const GenericMaterialProperty & -DerivativeMaterialInterface::getMaterialPropertyDerivative(const std::string & base, - const SymbolName & c1, - unsigned int v2, - unsigned int v3) -{ - return getMaterialPropertyDerivative( - base, - c1, - this->_coupled_standard_moose_vars[v2]->name(), - v3 == libMesh::invalid_uint ? "" : this->_coupled_standard_moose_vars[v3]->name()); -} -` ` ` -This snippet shows an overload that takes a `SymbolName` for the first variable and `unsigned int` indices for the second and third variables. It converts the `unsigned int` indices to variable names using `this->_coupled_standard_moose_vars[vX]->name()`. - -## Example: Implementing a CALPHAD-type Gibbs energy with sublattice models in C++ - -To implement a custom free energy, you would create a new C++ class that inherits from `DerivativeFunctionMaterialBase`. - -` ` `cpp -// In your custom material's header file (e.g., MyCalphadMaterial.h) -#pragma once - -#include "DerivativeFunctionMaterialBase.h" - -class MyCalphadMaterial : public DerivativeFunctionMaterialBase -{ -public: - static InputParameters validParams(); - MyCalphadMaterial(const InputParameters & parameters); - -protected: - virtual Real computeF() override; - virtual Real computeDF(unsigned int arg) override; - virtual Real computeD2F(unsigned int arg1, unsigned int arg2) override; - virtual Real computeD3F(unsigned int arg1, unsigned int arg2, unsigned int arg3) override; - -private: - // Declare coupled variables for concentrations, temperature, etc. - const VariableValue & _c1; - const VariableValue & _c2; - const VariableValue & _temp; - - unsigned int _c1_var; - unsigned int _c2_var; - unsigned int _temp_var; -}; -` ` ` - -` ` `cpp -// In your custom material's source file (e.g., MyCalphadMaterial.C) -#include "MyCalphadMaterial.h" - -registerMooseObject("MyPhaseFieldApp", MyCalphadMaterial); - -InputParameters -MyCalphadMaterial::validParams() -{ - InputParameters params = DerivativeFunctionMaterialBase::validParams(); - params.addClassDescription("Custom CALPHAD-type Gibbs Free Energy Material"); - params.addRequiredCoupledVar("c1", "First concentration variable"); - params.addRequiredCoupledVar("c2", "Second concentration variable"); - params.addRequiredCoupledVar("temperature", "Temperature variable"); - return params; -} - -MyCalphadMaterial::MyCalphadMaterial(const InputParameters & parameters) - : DerivativeFunctionMaterialBase(parameters), - _c1(coupledValue("c1")), - _c2(coupledValue("c2")), - _temp(coupledValue("temperature")), - _c1_var(coupled("c1")), - _c2_var(coupled("c2")), - _temp_var(coupled("temperature")) -{ -} - -Real -MyCalphadMaterial::computeF() -{ - // Implement your CALPHAD Gibbs energy function here - // Example: G = c1*ln(c1) + c2*ln(c2) + (1-c1-c2)*ln(1-c1-c2) + ... - const Real c1 = _c1[_qp]; - const Real c2 = _c2[_qp]; - const Real temp = _temp[_qp]; - // ... complex CALPHAD expression ... - return c1 * std::log(c1) + c2 * std::log(c2) + (1.0 - c1 - c2) * std::log(1.0 - c1 - c2) + temp; // Placeholder -} - -Real -MyCalphadMaterial::computeDF(unsigned int arg) -{ - // Implement the first derivative of computeF with respect to the variable 'arg' - if (arg == _c1_var) - { - // dF/dc1 - return std::log(_c1[_qp]) + 1.0 - std::log(1.0 - _c1[_qp] - _c2[_qp]) - 1.0; // Placeholder - } - if (arg == _c2_var) - { - // dF/dc2 - return std::log(_c2[_qp]) + 1.0 - std::log(1.0 - _c1[_qp] - _c2[_qp]) - 1.0; // Placeholder - } - if (arg == _temp_var) - { - // dF/dT - return 1.0; // Placeholder - } - return 0.0; -} - -Real -MyCalphadMaterial::computeD2F(unsigned int arg1, unsigned int arg2) -{ - // Implement the second derivative of computeF - if (arg1 == _c1_var && arg2 == _c1_var) - { - // d2F/dc1dc1 - return 1.0 / _c1[_qp] + 1.0 / (1.0 - _c1[_qp] - _c2[_qp]); // Placeholder - } - if (arg1 == _c1_var && arg2 == _c2_var) - { - // d2F/dc1dc2 - return 1.0 / (1.0 - _c1[_qp] - _c2[_qp]); // Placeholder - } - // ... and so on for all combinations - return 0.0; -} - -Real -MyCalphadMaterial::computeD3F(unsigned int arg1, unsigned int arg2, unsigned int arg3) -{ - // Implement the third derivative of computeF (optional) - return 0.0; -} -` ` ` - -## Registering Derivatives for Kernels - -Kernels like `AllenCahn` and `SplitCHParsed` consume derivatives by requesting them from the material system using `getMaterialPropertyDerivative()`. - -For example, in `AllenCahn`, the first and second derivatives of the free energy `f_name` with respect to the order parameter `_var.name()` are retrieved: -` ` `cpp -AllenCahn::AllenCahn(const InputParameters & parameters) - : ACBulk(parameters), - _dFdEta(getMaterialPropertyDerivative("f_name", _var.name())), - _d2FdEta2(getMaterialPropertyDerivative("f_name", _var.name(), _var.name())), - _d2FdEtadarg(_n_args) -{ - // Iterate over all coupled variables - for (unsigned int i = 0; i < _n_args; ++i) - _d2FdEtadarg[i] = &getMaterialPropertyDerivative("f_name", _var.name(), i); -} -` ` ` -Here, `_dFdEta` stores $\frac{\partial F}{\partial \eta}$ and `_d2FdEta2` stores $\frac{\partial^2 F}{\partial \eta^2}$. The loop then retrieves mixed second derivatives $\frac{\partial^2 F}{\partial \eta \partial arg_i}$ for all other coupled variables. - -The `DerivativeFunctionMaterialBase` class automatically declares and registers these derivative properties based on the `computeF`, `computeDF`, `computeD2F`, and `computeD3F` methods you implement. When a kernel requests a derivative using `getMaterialPropertyDerivative()`, the material system looks up the corresponding property that was computed by your custom material. - -## Relationships - -` ` `mermaid -classDiagram - class Material { - +computeQpProperties() - } - class DerivativeMaterialPropertyNameInterface { - +derivativePropertyNameFirst() - +derivativePropertyNameSecond() - +derivativePropertyNameThird() - } - class DerivativeMaterialInterface { - +getMaterialPropertyDerivative() - +declarePropertyDerivative() - } - class FunctionMaterialBase { - +computeProperties() - } - class DerivativeFunctionMaterialBase { - +computeF() - +computeDF(arg) - +computeD2F(arg1, arg2) - +computeD3F(arg1, arg2, arg3) - } - class AllenCahn { - -_dFdEta - -_d2FdEta2 - -_d2FdEtadarg - } - class SplitCHParsed { - -_dFdc - -_d2Fdc2 - -_d2Fdcdarg - } - class MyCalphadMaterial { - +computeF() - +computeDF(arg) - +computeD2F(arg1, arg2) - +computeD3F(arg1, arg2, arg3) - } - - DerivativeMaterialInterface <|-- DerivativeFunctionMaterialBase : public - DerivativeMaterialPropertyNameInterface <|-- DerivativeMaterialInterface : public - FunctionMaterialBase <|-- DerivativeFunctionMaterialBase : public - DerivativeMaterialInterface <|-- AllenCahn : public - DerivativeMaterialInterface <|-- SplitCHParsed : public - DerivativeFunctionMaterialBase <|-- MyCalphadMaterial : public - - AllenCahn ..> DerivativeMaterialInterface : uses getMaterialPropertyDerivative() - SplitCHParsed ..> DerivativeMaterialInterface : uses getMaterialPropertyDerivative() - MyCalphadMaterial ..> Material : provides properties -` ` ` - -## Notes -The `DerivativeParsedMaterial` is a related class that automatically performs symbolic differentiation for free energy functions defined by string expressions in the input file. However, the user's query specifically asks about cases "too complex for string parsing," which points to implementing a custom C++ material inheriting from `DerivativeFunctionMaterialBase`. The `MathFree - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-eigenstrains.md b/packages/akms/src/akms/_bundled/global_nodes/moose-eigenstrains.md deleted file mode 100644 index 329e1a5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-eigenstrains.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -id: moose-eigenstrains -title: MOOSE Eigenstrains and thermal expansion -domain: constitutive -subdomain: algorithmic -tags: -- eigenstrain -- thermal-expansion -- CTE -- stress-free-strain -- additive-decomposition -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-strain-formulations - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-strain-formulations ---- - -# MOOSE Eigenstrains and thermal expansion - -MOOSE handles eigenstrains by subtracting them from the total strain to compute the mechanical strain. This is managed through a base class `ComputeEigenstrainBase` and its derived classes, which register eigenstrains that are then collected and subtracted by strain calculator materials like `ComputeStrainBase` . Multiple eigenstrains are combined additively. - -## Classes & Methods - -* `ComputeEigenstrainBaseTempl::computeQpEigenstrain()`: An overridden method in derived eigenstrain classes responsible for calculating and storing the eigenstrain tensor at each quadrature point . -* `ComputeStrainBase::ComputeStrainBase()`: Constructor that retrieves a list of eigenstrain material properties based on user input . -* `ComputeStrainBase::computeProperties()` (or derived classes like `ComputeRSphericalSmallStrain::computeProperties()` ): This method calculates the total strain and then subtracts all registered eigenstrains to determine the mechanical strain. -* `ComputeThermalExpansionEigenstrainTempl::computeThermalStrain()`: Calculates the thermal strain based on the thermal expansion coefficient and temperature difference . -* `ComputeThermalExpansionEigenstrainBaseTempl::computeQpEigenstrain()`: Sets the eigenstrain property based on the computed thermal strain and handles derivatives for Jacobian calculations . - -## Equations - -The mechanical strain ($\boldsymbol{\epsilon}_{mech}$) is computed by subtracting the sum of all eigenstrains ($\boldsymbol{\epsilon}_{eigen}$) from the total strain ($\boldsymbol{\epsilon}_{total}$) . -$$ -\boldsymbol{\epsilon}_{mech} = \boldsymbol{\epsilon}_{total} - \sum_{i} \boldsymbol{\epsilon}_{eigen,i} \quad (1) -$$ -For `ComputeThermalExpansionEigenstrain`, the thermal eigenstrain ($\boldsymbol{\epsilon}^{thermal}$) is calculated as: -$$ -\boldsymbol{\epsilon}^{thermal} = \alpha \cdot \left( T - T_{stress\_free} \right) \boldsymbol{I} \quad (2) -$$ -where $\alpha$ is the thermal expansion coefficient, $T$ is the current temperature, $T_{stress\_free}$ is the stress-free temperature, and $\boldsymbol{I}$ is the identity matrix . - -## Algorithm Steps - -### Eigenstrain Registration and Subtraction - -1. **Define Eigenstrain Material:** Create a material that inherits from `ComputeEigenstrainBase` (e.g., `ComputeThermalExpansionEigenstrain` ). This material will compute a specific eigenstrain tensor. -2. **Register Eigenstrain Name:** In the input file, assign a unique `eigenstrain_name` to each eigenstrain material . -3. **Specify Eigenstrains in Strain Calculator:** In the `ComputeStrainBase` (or derived strain calculator) block, list the `eigenstrain_names` parameter with all the eigenstrains to be considered . -4. **Collect Eigenstrains:** The `ComputeStrainBase` constructor collects pointers to the material properties corresponding to the specified `eigenstrain_names` into the `_eigenstrains` vector . -5. **Compute Total Strain:** The strain calculator computes the total strain based on displacements . -6. **Subtract Eigenstrains:** In the `computeProperties()` method of the strain calculator, each eigenstrain in the `_eigenstrains` vector is subtracted from the `_total_strain` to yield the `_mechanical_strain` . - -` ` `pseudocode -function computeProperties() - for each quadrature point qp - compute _total_strain[qp] from displacements - _mechanical_strain[qp] = _total_strain[qp] - for each eigenstrain es in _eigenstrains - _mechanical_strain[qp] -= (*es)[qp] - end for - end for -end function -` ` ` - -### Temperature-Dependent CTE in `ComputeThermalExpansionEigenstrain` - -1. **Define Thermal Expansion Coefficient:** The `ComputeThermalExpansionEigenstrain` class takes a `thermal_expansion_coeff` parameter . -2. **Compute Thermal Strain:** The `computeThermalStrain()` method calculates the thermal strain using the provided `_thermal_expansion_coeff`, current `_temperature`, and `_stress_free_temperature` . -3. **Store Eigenstrain:** The calculated thermal strain is then stored in the `_eigenstrain` material property by `computeQpEigenstrain()` . - -## Parameters - -* `eigenstrain_names`: (vector of `MaterialPropertyName`) A list of material property names corresponding to the eigenstrain tensors to be subtracted from the total strain . Default is `{}`. -* `thermal_expansion_coeff`: (`Real`) The constant thermal expansion coefficient used by `ComputeThermalExpansionEigenstrain` . -* `stress_free_temperature`: (`Real`) The temperature at which the material is stress-free, used in thermal expansion calculations . -* `temperature`: (`MaterialPropertyName`) The name of the material property providing the current temperature . - -## Relationships - -` ` `mermaid -classDiagram - class Material - class ComputeEigenstrainBaseTempl { - +virtual void computeQpEigenstrain() - #GenericMaterialProperty& _eigenstrain - } - class ComputeThermalExpansionEigenstrainBaseTempl { - +virtual ValueAndDerivative computeThermalStrain() - #const std::vector~ValueAndDerivative~& _temperature - #const VariableValue& _stress_free_temperature - } - class ComputeThermalExpansionEigenstrainTempl { - #const Real& _thermal_expansion_coeff - } - class ComputeStrainBase { - #std::vector~const MaterialProperty~* _eigenstrains - #MaterialProperty~RankTwoTensor~& _mechanical_strain - #MaterialProperty~RankTwoTensor~& _total_strain - } - class ADComputeStrainBaseTempl { - #std::vector~const ADMaterialProperty~* _eigenstrains - #ADMaterialProperty~R2~& _mechanical_strain - #ADMaterialProperty~R2~& _total_strain - } - - Material <|-- ComputeEigenstrainBaseTempl - ComputeEigenstrainBaseTempl <|-- ComputeThermalExpansionEigenstrainBaseTempl - ComputeThermalExpansionEigenstrainBaseTempl <|-- ComputeThermalExpansionEigenstrainTempl - Material <|-- ComputeStrainBase - Material <|-- ADComputeStrainBaseTempl - - ComputeStrainBase "1" *-- "N" ComputeEigenstrainBaseTempl : "collects" - ADComputeStrainBaseTempl "1" *-- "N" ComputeEigenstrainBaseTempl : "collects" -` ` ` - -## MOOSE Input Syntax - -To define two thermal eigenstrains and apply them in a strain calculation: - -` ` `ini -[Materials] - [./elasticity_tensor] - type = ComputeIsotropicElasticityTensor - youngs_modulus = 2.1e5 - poissons_ratio = 0.3 - [../] - [./small_strain] - type = ComputeIncrementalStrain - eigenstrain_names = 'eigenstrain1 eigenstrain2' - [../] - [./thermal_expansion_strain1] - type = ComputeThermalExpansionEigenstrain - stress_free_temperature = 298 - thermal_expansion_coeff = 1.0e-5 - temperature = temp - eigenstrain_name = eigenstrain1 - [../] - [./thermal_expansion_strain2] - type = ComputeThermalExpansionEigenstrain - stress_free_temperature = 298 - thermal_expansion_coeff = 0.3e-5 - temperature = temp - eigenstrain_name = eigenstrain2 - [../] -[] -` ` ` - -## Notes - -### Multiple Eigenstrains - -MOOSE supports multiple eigenstrains, which are combined additively. The `ComputeStrainBase` class (and its Automatic Differentiation counterpart `ADComputeStrainBaseTempl`) stores a vector of pointers to `MaterialProperty` named `_eigenstrains` . During the strain computation, each of these registered eigenstrains is subtracted from the total strain . - -### Finite Strain Formulations - -The provided context primarily focuses on small strain formulations (e.g., `ComputeRSphericalSmallStrain` , `Compute1DSmallStrain` ). While the base classes `ComputeEigenstrainBase` and `ComputeStrainBase` are generic, the specific interaction of eigenstrains with finite strain formulations would depend on the implementation of finite strain calculators, which are not explicitly detailed in the provided snippets. However, the general principle of subtracting eigenstrains from the total strain to get mechanical strain is expected to hold. - -### Stress-Free Strains and Derivatives for Jacobian - -For thermal eigenstrains, the `_stress_free_temperature` is a crucial parameter . The `ComputeThermalExpansionEigenstrainBaseTempl::computeQpEigenstrain()` method also handles the computation of derivatives of the eigenstrain with respect to temperature (`_deigenstrain_dT`) for Jacobian calculations, especially when Automatic Differentiation (AD) is not used directly (`is_ad == false`) . This ensures that the Jacobian matrix, essential for Newton-Raphson solvers, correctly accounts for the influence of eigenstrains. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-elasticity-tensor.md b/packages/akms/src/akms/_bundled/global_nodes/moose-elasticity-tensor.md deleted file mode 100644 index ecbd820..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-elasticity-tensor.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -id: moose-elasticity-tensor -title: MOOSE Elastic stiffness tensor computation -domain: constitutive -subdomain: algorithmic -tags: -- elasticity-tensor -- rank-four-tensor -- symmetry -- rotation -- isotropic -- anisotropic -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-stress-computation-chain - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-stress-computation-chain -- to: cm-tensor-calculus - type: implements - weight: 0.8 - note: RankFourTensor for elasticity with symmetry classes ---- - -# MOOSE Elastic stiffness tensor computation - -# Answer - -You're asking about how MOOSE computes and stores elasticity tensors, specifically covering the `ComputeElasticityTensor` class hierarchy, the `RankFourTensor` data structure, tensor rotation for crystal orientations, and how tensors flow to stress computation. - -## Classes & Methods - - - -**Base Class Hierarchy:** -- `ComputeElasticityTensorBaseTempl` — abstract base for all elasticity tensor computations; declares `_elasticity_tensor` MaterialProperty and pure virtual `computeQpElasticityTensor()` -- `ComputeRotatedElasticityTensorBaseTempl` — intermediate class that adds Euler angle and rotation matrix support -- `ComputeElasticityTensorTempl` — concrete implementation for general anisotropic tensors with symmetry fill methods - -**Key Methods:** -- `ComputeElasticityTensorBaseTempl::computeQpProperties()` — orchestrates tensor computation and applies optional prefactor function -- `ComputeElasticityTensorTempl::computeQpElasticityTensor()` — assigns `_Cijkl` to `_elasticity_tensor[_qp]` -- `RankFourTensor::rotate(RealTensorValue)` — rotates tensor using $C'_{ijkl} = R_{im} R_{jn} R_{ko} R_{lp} C_{mnop}$ - -## Symmetry Class Handling - - - -Symmetry is handled via the `fill_method` parameter passed to `RankFourTensor` constructor: - -- **Isotropic** (`symmetric_isotropic`, `symmetric_isotropic_E_nu`): Detected via `_Cijkl.isIsotropic()` and guaranteed as `ISOTROPIC` -- **Orthotropic/Cubic** (`symmetric9`): 9 independent components; used for cubic crystals and orthotropic materials -- **General Anisotropic** (`symmetric21`): 21 independent components with full symmetries $C_{ijkl} = C_{jikl} = C_{ijlk} = C_{klij}$ -- **Transverse Isotropic** (`axisymmetric_rz`): 5 independent components -- **No Symmetry** (`general`): All 81 components - -The fill method is specified in the input file and determines how the input vector is mapped to the full 3×3×3×3 tensor. - -## RankFourTensor Data Structure - -The codebase context does not contain the `RankFourTensor` header or implementation details. I cannot describe the internal storage layout (e.g., whether it uses a flat array, nested vectors, or sparse representation) or the access patterns without seeing the class definition. To answer this part fully, I would need access to `modules/solid_mechanics/include/materials/RankFourTensor.h` and its implementation. - -What I can confirm is that `RankFourTensor` is instantiated with a vector of Real values and a `FillMethod` enum: - -` ` `cpp -_Cijkl(this->template getParam>("C_ijkl"), - (RankFourTensor::FillMethod)(int)this->template getParam("fill_method")) -` ` ` - -## Rotation of Elasticity Tensor - - - -**For static rotations** (initial setup only): -- `ComputeElasticityTensor` rotates the tensor once during construction -- If `rotation_matrix` parameter is provided, it applies directly: `_Cijkl.rotate(_rotation_matrix)` -- Otherwise, it builds a `RotationTensor` from Euler angles (Bunge convention, $Z_1 X_2 Z_3$ extrinsic) and applies: `_Cijkl.rotate(R)` - -**For dynamic rotations** (crystal plasticity): -- `ComputeElasticityTensorCP` overrides `computeQpElasticityTensor()` to rotate at every timestep -- It uses active rotation (transpose of passive Bunge angles) and updates the rotation matrix from coupled Euler angle variables or a property file -- The rotation is applied as: `_elasticity_tensor[_qp].rotate(_crysrot[_qp])` - -**Rotation Equation:** -$$C'_{ijkl} = R_{im} R_{jn} R_{ko} R_{lp} C_{mnop} \quad (1)$$ - -where $R$ is the rotation matrix (passive convention in `ComputeElasticityTensor`, active in `ComputeElasticityTensorCP`). - -## MaterialProperty Data Flow - - - -The elasticity tensor is declared as a `GenericMaterialProperty` reference: - -` ` `cpp -GenericMaterialProperty & _elasticity_tensor; -` ` ` - -where `T` is either `RankFourTensor` or `SymmetricRankFourTensor`. The property name is stored in `_elasticity_tensor_name` (default: `"elasticity_tensor"` or `"{base_name}_elasticity_tensor"` if a base name is provided). - -**Flow to stress computation:** -1. `ComputeElasticityTensorBase::computeQpProperties()` calls `computeQpElasticityTensor()` -2. Derived classes populate `_elasticity_tensor[_qp]` with the computed tensor -3. Stress materials (e.g., `ComputeLinearElasticStress`) retrieve the property via `getMaterialProperty("elasticity_tensor")` and use it to compute $\sigma_{ij} = C_{ijkl} \epsilon_{kl}$ - -## Parameters - - - -` ` `ini -C_ijkl = > # Required: stiffness tensor components -fill_method = symmetric9 # Optional: symmetry class (default: symmetric9) - # Options: symmetric21, symmetric9, orthotropic, - # symmetric_isotropic, axisymmetric_rz, etc. -euler_angle_1 = 0.0 # Optional: first Euler angle (degrees) -euler_angle_2 = 0.0 # Optional: second Euler angle (degrees) -euler_angle_3 = 0.0 # Optional: third Euler angle (degrees) -rotation_matrix = # Optional: 3×3 rotation matrix (overrides Euler angles) -elasticity_tensor_prefactor = # Optional: scalar multiplier function -base_name = "" # Optional: prefix for material property names -` ` ` - -## Relationships - -` ` `mermaid -graph TD - A["ComputeElasticityTensorBase
(abstract base)"] - B["ComputeRotatedElasticityTensorBase
(adds Euler angles)"] - C["ComputeElasticityTensor
(general anisotropic)"] - D["ComputeIsotropicElasticityTensor
(isotropic only)"] - E["ComputeElasticityTensorCP
(crystal plasticity)"] - F["RankFourTensor
(data structure)"] - G["RotationTensor
(rotation matrix)"] - H["StressCompute
(uses elasticity tensor)"] - - A -->|declares| F - B -->|extends| A - B -->|uses| G - C -->|extends| B - C -->|instantiates| F - D -->|extends| A - E -->|extends| C - E -->|rotates at each step| F - F -->|passed via MaterialProperty| H -` ` ` - -## Code Snippets - -**Constructor with symmetry handling:** - - -**Tensor assignment to MaterialProperty:** - - -**Crystal plasticity dynamic rotation:** - - -## MOOSE Input Syntax - -` ` `ini -[Materials] - [elasticity_tensor] - type = ComputeElasticityTensor - C_ijkl = '1.0 0.5 0.5 1.0 0.5 1.0 0.25 0.25 0.25' - fill_method = symmetric9 - euler_angle_1 = 0.0 - euler_angle_2 = 0.0 - euler_angle_3 = 0.0 - base_name = material1 - [] -[] -` ` ` - -For isotropic materials: -` ` `ini -[Materials] - [elasticity_tensor] - type = ComputeIsotropicElasticityTensor - youngs_modulus = 210e9 - poissons_ratio = 0.3 - [] -[] -` ` ` - -For crystal plasticity with dynamic rotation: -` ` `ini -[Materials] - [elasticity_tensor] - type = ComputeElasticityTensorCP - C_ijkl = '1.0 0.5 0.5 1.0 0.5 1.0 0.25 0.25 0.25' - fill_method = symmetric9 - euler_angle_variables = 'euler_1 euler_2 euler_3' - [] -[] -` ` ` - -## Notes - -The codebase context does not include the `RankFourTensor` class definition, so I cannot provide details on its internal storage layout or element access patterns. The documentation references engineering notation (6×6 matrix) and Einstein index notation (4-index), but the actual 3×3×3×3 storage mechanism is not visible in the provided snippets. - -`ComputeElasticityTensorCP` differs from `ComputeElasticityTensor` in two key ways: (1) it uses **active** rotation (transpose of Bunge angles) rather than passive, and (2) it rotates the tensor at every material timestep, not just during initialization. This is critical for crystal plasticity simulations where the crystal frame evolves with plastic deformation. - -The `_elasticity_tensor` MaterialProperty is templated on `is_ad` (automatic differentiation flag), allowing both regular and AD-enabled stress computations to use the same material class. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-factory-registration.md b/packages/akms/src/akms/_bundled/global_nodes/moose-factory-registration.md deleted file mode 100644 index c84fdbf..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-factory-registration.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -id: moose-factory-registration -title: MOOSE Object factory and registration pattern -domain: architecture -subdomain: procedural -tags: -- factory-pattern -- registerMooseObject -- validParams -- input-parameters -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-object-factory - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-object-factory ---- - -# MOOSE Object factory and registration pattern - -The MOOSE framework utilizes a robust object factory and registration system to dynamically create objects based on input file specifications. This system is centered around the `MooseObjectFactory` (referred to as `Factory` in the code) and the `Registry` . Classes declare their input parameters using a `static InputParameters validParams()` method , which the factory uses to validate and construct objects. - -## 1. How `registerMooseObject()` macro works - -The `registerMooseObject()` macro is used to register a C++ class with the MOOSE framework's `Registry` . This macro creates a static character variable whose initialization calls `Registry::add()` . - -It registers the class name (as a string) along with a factory function (implicitly, through the template `classname`) that can create an instance of that class . This allows the `Factory` to later construct objects of this type using only their string name from the input file . - -**Code Snippet:** -` ` `cpp -#define registerMooseObject(app, classname) \ - static char combineNames(dummyvar_for_registering_obj_##classname, __COUNTER__) = \ - Registry::add({app, #classname, "", "", __FILE__, __LINE__, "", ""}) -` ` ` - -**Example Usage:** -` ` `cpp -registerMooseObject("MooseApp", BlockWeightedPartitioner); -` ` ` -This line registers the `BlockWeightedPartitioner` class with the "MooseApp" application label . - -## 2. The `MooseObjectFactory` (referred to as `Factory`) - -The `Factory` class is responsible for creating MOOSE objects from input file type strings. When an object needs to be created, the `Factory::create()` method is called with the object's type name (string), instance name, and `InputParameters` . - -The `createTempl` method (a template function underlying `create`) first retrieves the `RegistryEntryBase` associated with the `obj_name` from its internal map `_name_to_object` . This `RegistryEntryBase` contains the necessary information, including a factory function, to construct the actual C++ object . The `build()` or `buildShared()` method of the `registry_entry` is then invoked, passing the validated `InputParameters` to the object's constructor . - -## 3. `validParams()` — how each class declares its input parameters - -Every `MooseObject` (and its derived classes) declares its input parameters by implementing a `static InputParameters validParams()` method . This method returns an `InputParameters` object that defines all the parameters the class can accept, including their types, default values, and documentation strings . - -This follows a template pattern where each class explicitly defines its own parameter interface . Derived classes typically start by calling the `validParams()` method of their parent class to inherit parameters, then add their own specific parameters . - -**Code Snippet:** -` ` `cpp -InputParameters -Convection::validParams() -{ - InputParameters params = Kernel::validParams(); // Start with parent - params.addRequiredParam("velocity", "Velocity Vector"); - params.addParam("coefficient", "Diffusion coefficient"); - return params; -} -` ` ` - -## 4. Parameter types: `MooseEnum`, `std::vector<>`, coupled variable references - -MOOSE supports various parameter types, including: -* **`MooseEnum`**: A "smart" enum utility that handles both integer and string contexts and is self-checked for consistency . It is declared by providing a space-separated list of valid options and an optional default value . - **Example:** - ` ` `cpp - MooseEnum order( - "CONSTANT FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH EIGHTH NINTH TENTH ELEVENTH TWELFTH " - "THIRTEENTH FOURTEENTH FIFTEENTH SIXTEENTH SEVENTEENTH EIGHTTEENTH NINETEENTH TWENTIETH " - "TWENTYFIRST TWENTYSECOND TWENTYTHIRD TWENTYFOURTH TWENTYFIFTH TWENTYSIXTH TWENTYSEVENTH " - "TWENTYEIGHTH TWENTYNINTH THIRTIETH THIRTYFIRST THIRTYSECOND THIRTYTHIRD THIRTYFOURTH " - "THIRTYFIFTH THIRTYSIXTH THIRTYSEVENTH THIRTYEIGHTH THIRTYNINTH FORTIETH FORTYFIRST " - "FORTYSECOND FORTYTHIRD", - "FIRST", - true); - params.addParam("order", - order, - "Order of the FE shape function to use for this variable (additional " - "orders not listed here are allowed, depending on the family)."); - ` ` ` - -* **`std::vector<>`**: Standard C++ vectors are supported for lists of values . - **Example:** - ` ` `cpp - params.addRequiredParam>( - "block", "The list of block ids (SubdomainID) that this object will be applied"); - ` ` ` - -* **Coupled Variable References**: These are declared using `addCoupledVar()` . This method takes the variable name and an optional documentation string . - **Example:** - ` ` `cpp - params.addCoupledVar("temperature", 0.0, "Coupled temperature"); - params.addCoupledVar("external_fields", - "The external fields that can be used in the UMAT subroutine"); - ` ` ` - -## 5. Required vs optional parameters, default values, documentation strings - -The `InputParameters` class provides methods to define the characteristics of each parameter: -* **Required Parameters**: Declared using `addRequiredParam("name", "documentation string")` . These parameters *must* be supplied in the input file . - **Example:** - ` ` `cpp - params.addRequiredParam("month", "Provide the month you were born."); - ` ` ` - -* **Optional Parameters with Default Values**: Declared using `addParam("name", default_value, "documentation string")` . If the parameter is not provided in the input file, the specified `default_value` is used . - **Example:** - ` ` `cpp - params.addParam("year", 1980, "Provide the year you were born."); - ` ` ` - -* **Documentation Strings**: A string provided as the last argument to `addParam` or `addRequiredParam` . This string is used for generating documentation for the parameter . - -## 6. How the factory enforces parameter validation before object construction - -The `Factory` ensures parameter validation happens before object construction through a two-step process: -1. **`getValidParams()`**: When an object is requested, the `Factory` first calls `getValidParams()` on the registered class type to obtain a pristine `InputParameters` object containing all declared parameters and their default values . -2. **`initialize()`**: The `Factory::initialize()` method then takes the `InputParameters` provided by the user (from the input file) and merges them with the valid parameters obtained from `getValidParams()` . During this process, it performs validation, checking for required parameters, type correctness, and range constraints . -3. **Construction**: Only after successful validation and initialization of the `InputParameters` object is the actual object constructed by calling its constructor with the validated `InputParameters` . The `MooseObject` constructor itself contains an assertion to ensure it was constructed via the factory with validated parameters . - -## 7. The `InputParameters` class — key methods - -The `InputParameters` class is central to MOOSE's parameter system. Key methods include: -* `addRequiredParam("name", "doc_string")`: Adds a parameter that *must* be specified by the user . -* `addParam("name", default_value, "doc_string")`: Adds an optional parameter with a default value . -* `addCoupledVar("name", "doc_string")`: Adds a parameter that represents a coupled variable, allowing objects to depend on other variables in the simulation . - -## Complete pattern from `validParams()` declaration through factory construction - -### Classes & Methods: -* `MooseObject::validParams()`: Static method in `MooseObject` and its derivatives to declare input parameters . -* `InputParameters::addRequiredParam()`: Adds a mandatory parameter . -* `InputParameters::addParam()`: Adds an optional parameter, potentially with a default value . - -Wiki pages you might want to explore: -- [Core Application Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#2) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-input-file-anatomy.md b/packages/akms/src/akms/_bundled/global_nodes/moose-input-file-anatomy.md deleted file mode 100644 index 5972927..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-input-file-anatomy.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: moose-input-file-anatomy -title: MOOSE Input file structure and block composition -domain: architecture -subdomain: procedural -tags: -- input-file -- block-structure -- global-params -- parser -- type-system -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-action-system - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-action-system ---- - -# MOOSE Input file structure and block composition - -The MOOSE input file uses a hierarchical block structure to define a simulation, with top-level blocks like `[Mesh]`, `[Variables]`, `[Kernels]`, `[BCs]`, `[Materials]`, `[Executioner]`, and `[Outputs]` each responsible for specific aspects of the simulation setup . The input file is parsed into an Action/object hierarchy, where the `Parser` creates an abstract syntax tree, the `Builder` creates `Action` objects, and the `ActionWarehouse` executes these `Action`s to construct MOOSE objects via the `Factory` . - -## Top-Level Blocks and Their Responsibilities - -MOOSE input files are structured into blocks, with capital-letter blocks representing system-defined syntax . The essential top-level blocks are: - -* **`[Mesh]`**: Defines the geometry of the computational domain, often using mesh generator objects like `GeneratedMesh` . -* **`[Variables]`**: Declares the unknown field variables that the simulation will solve for . -* **`[Kernels]`**: Specifies the partial differential equations (PDEs) to be solved by adding `Kernel` objects, which represent the volumetric terms of the weak form . -* **`[BCs]`**: Defines the boundary conditions for the problem, such as Dirichlet or Neumann conditions, applied to specific boundaries of the mesh . -* **`[Materials]`**: Used to define material properties, which can be constant or depend on other variables . -* **`[Executioner]`**: Controls how the simulation progresses, including time-stepping schemes for transient problems or solver settings for steady-state problems . -* **`[Outputs]`**: Specifies how the simulation results are written, including format (e.g., ExodusII, CSV) and frequency . - -## Sub-blocks and the Type System - -Within top-level blocks, sub-blocks are used to define individual MOOSE objects . The `type = DirichletBC` syntax inside a `[BCs]` block invokes the factory system . The `Factory` is responsible for creating physics objects (Kernels, BCs, Materials, etc.) based on the `type` parameter specified in the input file . When `type = DirichletBC` is encountered, the `Factory` looks up the registered `DirichletBC` class and instantiates an object of that type, passing the parameters defined within its sub-block . - -## Block-Level Parameters vs. Object-Level Parameters - -Parameters can be defined at different levels within the input file hierarchy. -* **Block-level parameters** apply to the entire block. For example, `active` and `inactive` lists can be defined at the block level to control which sub-blocks are processed . -* **Object-level parameters** are specific to a particular MOOSE object defined within a sub-block. These parameters configure the behavior of that individual object, such as `variable` or `boundary` for a `DirichletBC` object . - -## `active`/`inactive` Lists for Toggling Objects - -The `active` and `inactive` parameters allow for selective processing of sub-blocks within an input file . -* `active`: If specified, only the sub-blocks named in this list will be visited and made active . -* `inactive`: If specified, sub-blocks matching these identifiers will be skipped . -These parameters are processed by the `Builder` during input file parsing . - -## The `[GlobalParams]` Block - -The `[GlobalParams]` block is used to define parameters that can be propagated to all objects in the simulation . While not explicitly detailed in the provided snippets, the `GlobalParamsAction` is involved in handling these parameters . This mechanism allows for setting common parameters once and having them applied universally, simplifying input files for complex simulations. - -## Include Files and Input File Inheritance - -MOOSE supports including other input files using the `!include` syntax . This allows for modular input files and can be used in any nested context . Functionally, including a file is equivalent to inserting its text at the `!include` location . Parameters from included files do not override parent parameters by default, and explicit override syntax (`:=` or `:override=`) is needed to change previously defined values . - -## Input File Parsing into Action/Object Hierarchy - -The input file parsing process involves several key components: -1. **Parser**: The `Parser` class uses the HIT (Hierarchical Input Text) parser to read the input file and create an abstract syntax tree (AST) . The `MooseApp` orchestrates this by calling `Parser::parse()` . -2. **Builder**: The `Builder` class then walks this AST and creates `Action` objects . The `MooseApp` calls `Builder::build()` . -3. **ActionWarehouse**: The created `Action` objects are stored in the `ActionWarehouse` . The `ActionWarehouse` manages and executes these `Action`s in dependency order . -4. **Factory**: As `Action`s are executed, they interact with the `Factory` to dynamically create MOOSE objects (e.g., Kernels, BCs, Materials) based on the `type` parameter specified in the input file . - -This pipeline transforms the declarative input file into a fully configured simulation object hierarchy within the `MooseApp` . - -## Relationships - -` ` `mermaid -graph LR - InputFile["Input File
(.i file)"] - Parser["Parser"] - HitTree["hit::Node
(AST)"] - Builder["Builder"] - Actions["Action Objects"] - ActionWarehouse["ActionWarehouse"] - Factory["Factory"] - MooseObjects["MOOSE Objects
(Kernels, BCs, etc.)"] - - InputFile --> Parser - Parser --> HitTree - HitTree --> Builder - Builder --> Actions - Actions --> ActionWarehouse - ActionWarehouse --> |"executeActions"| Factory - Factory --> MooseObjects -` ` ` - - -## Complete Minimal Input File for a Mechanics Problem - -Here is a minimal MOOSE input file for a mechanics problem, annotated with the purpose of each block. This example sets up a simple diffusion problem, which is analogous to a basic mechanics problem in terms of input file structure. - -` ` `ini -# This is a minimal MOOSE input file for a mechanics-like problem (diffusion) - -[Mesh] # Defines the geometry of the simulation domain. - type = GeneratedMesh # Uses a built-in mesh generator. - dim = 2 # Specifies a 2-dimensional mesh. - nx = 10 # Number of elements in the x-direction. - ny = 10 # Number of elements in the y-direction. -[] - -[Variables] # Declares the primary unknown variables to be solved. - [u] # Defines a variable named 'u'. - family = LAGRANGE # Uses Lagrange finite elements. - order = FIRST # Specifies first-order interpolation. - [] -[] - -[Kernels] # Defines the terms of the partial differential equations. - [diff] # A sub-block for a specific kernel. - type = Diffusion # Specifies the Diffusion kernel, representing -∇²u. - variable = u # Applies this kernel to the variable 'u'. - [] -[] - -[BCs] # Defines the boundary conditions for the problem. - [left_bc] # A sub-block for a boundary condition on the 'left' boundary. - type = DirichletBC # Specifies a Dirichlet boundary condition (fixed value). - variable = u # Applies to variable 'u'. - boundary = left # Applies to the boundary named 'left'. - value = 1.0 # Sets the value of 'u' to 1.0 on the 'left' boundary. - [] - [right_bc] # A sub-block for a boundary condition on the 'right' boundary. - type = DirichletBC - variable = u - boundary = right - value = 0.0 - [] -[] - -[Executioner] # Controls the simulation process (e.g., steady-state, transient). - type = Steady # Specifies a steady-state solver. - solve_type = NEWTON # Uses Newton's method for solving the nonlinear system. -[] - -[Outputs] # Specifies how and what results are saved. - exodus = true # Enables output in ExodusII format. -[] -` ` ` - - - - - - - -## Notes - -The provided context primarily focuses on the core MOOSE framework and its input file processing. While the prompt asks for a mechanics problem, the fundamental structure of the input file and the roles of the top-level blocks remain consistent across different physics applications. The example provided uses a diffusion problem as it directly relates to the available snippets illustrating basic input file structure. The `[GlobalParams]` block is mentioned in the `Builder.C` file as `GlobalParamsAction` , indicating its role in parameter propagation, - -Wiki pages you might want to explore: -- [Core Application Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#2) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-jfnk-architecture.md b/packages/akms/src/akms/_bundled/global_nodes/moose-jfnk-architecture.md deleted file mode 100644 index 38a2b0d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-jfnk-architecture.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -id: moose-jfnk-architecture -title: MOOSE JFNK solver architecture in MOOSE -domain: solver -subdomain: algorithmic -tags: -- JFNK -- matrix-free -- GMRES -- PETSc-SNES -- jacobian-vector-product -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-jfnk-preconditioning - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-jfnk-preconditioning -- to: cm-solver-matrixfree - type: implements - weight: 0.9 - note: JFNK matrix-free Newton-Krylov architecture ---- - -# MOOSE JFNK solver architecture in MOOSE - -MOOSE leverages PETSc's SNES (Scalable Nonlinear Equation Solvers) component to configure Newton-based nonlinear iterations, including Jacobian-Free Newton-Krylov (JFNK) methods . The core of JFNK in MOOSE involves approximating the Jacobian-vector product using a finite-difference approach, which is then utilized by Krylov subspace methods like GMRES for the linear solve . For preconditioning, MOOSE assembles an approximate Jacobian matrix, even when the full Jacobian is not explicitly formed . - -## Newton Nonlinear Iteration Setup with PETSc SNES - -MOOSE sets up the Newton nonlinear iteration by interfacing with PETSc's SNES component through the `NonlinearSystem` class . The `NonlinearSystem::getSNES()` method retrieves the PETSc SNES object, allowing MOOSE to configure its behavior . The overall nonlinear problem is represented as $\mathbf{R}(\mathbf{u}) = \mathbf{0}$ , and Newton's method iteratively solves the linear system $\mathbf{J}(\mathbf{u}^{i-1}) \delta \mathbf{u}^{i} = -\mathbf{R}(\mathbf{u}^{i-1})$ at each step . - -## Matrix-Free Jacobian-Vector Product Approximation - -For JFNK, MOOSE approximates the Jacobian-vector product $\mathbf{J}(\mathbf{u}^{i-1}) \mathbf{y}$ using a finite-difference like approximation : - -$$ -\mathbf{J}(\mathbf{u}^{i-1}) \mathbf{y} \approx \frac{\mathbf{R}(\mathbf{u}^{i-1} + \epsilon \mathbf{y}) - \mathbf{R}(\mathbf{u}^{i-1})}{\epsilon} \quad (1) -$$ - -Here, $\mathbf{R}(\mathbf{u})$ is the residual vector, $\mathbf{u}$ is the current solution vector, $\mathbf{y}$ is a perturbation vector, and $\epsilon$ is a scalar chosen by PETSc to ensure accuracy . This approximation avoids the explicit formation of the Jacobian matrix . The `mffd_type` parameter in the `[Executioner]` block can specify the finite differencing type, with "wp" (Walker and Pernice) being the default . - -## Krylov Method (GMRES) and Jv Product - -Krylov methods, such as GMRES (Generalized Minimal Residual method), are used to solve the linear system arising from each Newton iteration . GMRES is the default linear solution algorithm in PETSc and MOOSE due to its flexibility, as it does not assume properties like symmetry for the Jacobian . The Krylov method uses the matrix-free Jacobian-vector product (Equation 1) to construct the Krylov subspace without explicitly forming the Jacobian matrix . During each linear step of JFNK, the `computeQpResidual` method is called to approximate the action of the Jacobian on the Krylov vector . - -## Preconditioning Matrix in JFNK - -Even with JFNK, preconditioning is crucial for efficient convergence . In MOOSE, when using Preconditioned JFNK (`PJFNK`), an approximate Jacobian matrix $\mathbf{M}$ is assembled for preconditioning . This preconditioning matrix is typically easier to compute than the exact Jacobian and is used to improve the convergence of the Krylov solver . By default, MOOSE uses block-diagonal preconditioning, where each block corresponds to a single MOOSE variable . The `computeQpJacobian` and `computeQpOffDiagJacobian` methods are used to compute values for this preconditioning matrix . - -## `solve_type = JFNK` vs `solve_type = NEWTON` - -MOOSE provides different `solve_type` options in the `[Executioner]` block : - -* **`JFNK`**: Jacobian-Free Newton-Krylov . This option activates matrix-free Jacobian-vector products and does not assemble a preconditioning matrix . It is generally used when forming the full Jacobian is too expensive or complex, but it often performs poorly without preconditioning . -* **`PJFNK`**: Preconditioned Jacobian-Free Newton-Krylov . This is the default solve type . It uses matrix-free Jacobian-vector products but includes a preconditioner built from an approximate Jacobian matrix . This is generally preferred over `JFNK` for better convergence. -* **`NEWTON`**: Full Newton Solve . This option uses the Jacobian provided by kernels (which may not be exact) for the Krylov solve . It requires an accurate Jacobian for effective convergence . - -The choice between `JFNK`, `PJFNK`, and `NEWTON` depends on the problem's nonlinearity, the cost of forming the Jacobian, and the desired convergence properties. `PJFNK` is often a good balance, providing robustness without the full cost of assembling an exact Jacobian. - -## Key PETSc Options and MOOSE Equivalents - -MOOSE allows users to configure PETSc options through parameters in the `[Executioner]` block . - -* **`-snes_type`**: Controls the type of nonlinear solver. - * MOOSE's `solve_type` parameter maps to this. For example, `solve_type = JFNK` or `solve_type = PJFNK` internally configures the SNES type for matrix-free operation . -* **`-ksp_type`**: Controls the type of Krylov subspace method for the linear solve. - * GMRES is the default in MOOSE . You can set this directly using `petsc_options_iname = '-ksp_type'` and `petsc_options_value = 'gmres'` . -* **`-pc_type`**: Controls the type of preconditioner. - * MOOSE's default preconditioning is block-diagonal . Common options include `ilu` (incomplete LU), `bjacobi` (block Jacobi), `asm` (Additive Schwartz Method), `lu` (full LU), `gamg` (Geometric AMG), and `hypre` (Hypre preconditioners like BoomerAMG) . These can be set via `petsc_options_iname = '-pc_type'` and `petsc_options_value = 'ilu'` (or other types) . - -### MOOSE `[Executioner]` Block Parameters - -` ` `ini -[Executioner] - type = Steady - solve_type = PJFNK # or JFNK, NEWTON, FD, LINEAR - petsc_options_iname = '-snes_type -ksp_type -pc_type -ksp_gmres_restart -pc_asm_overlap' - petsc_options_value = 'newtonls gmres bjacobi 30 2' -[] -` ` ` - -## Convergence Monitors - -MOOSE provides several convergence monitors for both nonlinear and linear solves: - -* **Nonlinear Residual Norm**: MOOSE prints the norm of the nonlinear residual, $\|\vec{R}(\vec{u}_n)\|$, at each Newton iteration . Convergence is typically checked against absolute (`nl_abs_tol`) and relative (`nl_rel_tol`) tolerances . -* **Linear Residual Norm**: For the linear solve within each Newton iteration, MOOSE can print the norm of the linear residual, $\|\vec{\rho}_k\|$, if `print_linear_residuals = true` is set in the `[Outputs]` block . -* **SNES Line Search**: PETSc's SNES line search monitors the step size $\alpha$ in the update $\mathbf{u}^{i} = \mathbf{u}^{i-1} + \alpha \delta \mathbf{u}^{i}$ . The line search type can be controlled by PETSc options like `-snes_linesearch_type` . - -## Classes & Methods - -* `NonlinearSystem::getSNES()`: Retrieves the PETSc SNES object for the nonlinear system . -* `FEProblemBase::computeResidualSys()`: Computes the residual vector for a given system . -* `FEProblemBase::computeJacobianSys()`: Computes the Jacobian matrix for a given system . -* `Moose::ST_JFNK`, `Moose::ST_PJFNK`, `Moose::ST_NEWTON`: Enumerations defining the solve types . - -## Equations - -1. **Newton's Method Linear System**: - $$ - \mathbf{J}(\mathbf{u}^{i-1}) \delta \mathbf{u}^{i} = -\mathbf{R}(\mathbf{u}^{i-1}) - $$ -2. **Matrix-Free Jacobian-Vector Product Approximation**: - $$ - \mathbf{J}(\mathbf{u}^{i-1}) \mathbf{y} \approx \frac{\mathbf{R}(\mathbf{u}^{i-1} + \epsilon \mathbf{y}) - \mathbf{R}(\mathbf{u}^{i-1})}{\epsilon} - $$ -3. **Nonlinear Solution Update**: - $$ - \mathbf{u}^{i} = \mathbf{u}^{i-1} + \alpha \delta \mathbf{u}^{i} - $$ - -## Parameters - -* `solve_type`: `MooseEnum` (`PJFNK`, `JFNK`, `NEWTON`, `FD`, `LINEAR`). Default is `PJFNK`. Controls the general method for - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-jfnk-preconditioning.md b/packages/akms/src/akms/_bundled/global_nodes/moose-jfnk-preconditioning.md deleted file mode 100644 index 512e418..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-jfnk-preconditioning.md +++ /dev/null @@ -1,234 +0,0 @@ ---- -id: moose-jfnk-preconditioning -title: MOOSE Solver Configuration — JFNK and Preconditioning -domain: solver -subdomain: algorithmic -tags: -- JFNK -- newton-krylov -- preconditioning -- SMP -- AMG -- PETSc -- automatic-differentiation -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-petsc-interface - type: requires - weight: 0.8 - note: JFNK solver configured through PETSc interface -- to: cm-solver-matrixfree - type: implements - weight: 0.8 - note: Implements matrix-free JFNK with physics-based preconditioning ---- - -# MOOSE Solver Configuration — JFNK and Preconditioning - -Framework knowledge node covering 2 aspect(s) of Solver Configuration — JFNK and Preconditioning. - -## JFNK solver architecture in MOOSE - -MOOSE leverages PETSc's SNES (Scalable Nonlinear Equation Solvers) component to configure Newton-based nonlinear iterations, including Jacobian-Free Newton-Krylov (JFNK) methods . The core of JFNK in MOOSE involves approximating the Jacobian-vector product using a finite-difference approach, which is then utilized by Krylov subspace methods like GMRES for the linear solve . For preconditioning, MOOSE assembles an approximate Jacobian matrix, even when the full Jacobian is not explicitly formed . - -## Newton Nonlinear Iteration Setup with PETSc SNES - -MOOSE sets up the Newton nonlinear iteration by interfacing with PETSc's SNES component through the `NonlinearSystem` class . The `NonlinearSystem::getSNES()` method retrieves the PETSc SNES object, allowing MOOSE to configure its behavior . The overall nonlinear problem is represented as $\mathbf{R}(\mathbf{u}) = \mathbf{0}$ , and Newton's method iteratively solves the linear system $\mathbf{J}(\mathbf{u}^{i-1}) \delta \mathbf{u}^{i} = -\mathbf{R}(\mathbf{u}^{i-1})$ at each step . - -## Matrix-Free Jacobian-Vector Product Approximation - -For JFNK, MOOSE approximates the Jacobian-vector product $\mathbf{J}(\mathbf{u}^{i-1}) \mathbf{y}$ using a finite-difference like approximation : - -$$ -\mathbf{J}(\mathbf{u}^{i-1}) \mathbf{y} \approx \frac{\mathbf{R}(\mathbf{u}^{i-1} + \epsilon \mathbf{y}) - \mathbf{R}(\mathbf{u}^{i-1})}{\epsilon} \quad (1) -$$ - -Here, $\mathbf{R}(\mathbf{u})$ is the residual vector, $\mathbf{u}$ is the current solution vector, $\mathbf{y}$ is a perturbation vector, and $\epsilon$ is a scalar chosen by PETSc to ensure accuracy . This approximation avoids the explicit formation of the Jacobian matrix . The `mffd_type` parameter in the `[Executioner]` block can specify the finite differencing type, with "wp" (Walker and Pernice) being the default . - -## Krylov Method (GMRES) and Jv Product - -Krylov methods, such as GMRES (Generalized Minimal Residual method), are used to solve the linear system arising from each Newton iteration . GMRES is the default linear solution algorithm in PETSc and MOOSE due to its flexibility, as it does not assume properties like symmetry for the Jacobian . The Krylov method uses the matrix-free Jacobian-vector product (Equation 1) to construct the Krylov subspace without explicitly forming the Jacobian matrix . During each linear step of JFNK, the `computeQpResidual` method is called to approximate the action of the Jacobian on the Krylov vector . - -## Preconditioning Matrix in JFNK - -Even with JFNK, preconditioning is crucial for efficient convergence . In MOOSE, when using Preconditioned JFNK (`PJFNK`), an approximate Jacobian matrix $\mathbf{M}$ is assembled for preconditioning . This preconditioning matrix is typically easier to compute than the exact Jacobian and is used to improve the convergence of the Krylov solver . By default, MOOSE uses block-diagonal preconditioning, where each block corresponds to a single MOOSE variable . The `computeQpJacobian` and `computeQpOffDiagJacobian` methods are used to compute values for this preconditioning matrix . - -## `solve_type = JFNK` vs `solve_type = NEWTON` - -MOOSE provides different `solve_type` options in the `[Executioner]` block : - -* **`JFNK`**: Jacobian-Free Newton-Krylov . This option activates matrix-free Jacobian-vector products and does not assemble a preconditioning matrix . It is generally used when forming the full Jacobian is too expensive or complex, but it often performs poorly without preconditioning . -* **`PJFNK`**: Preconditioned Jacobian-Free Newton-Krylov . This is the default solve type . It uses matrix-free Jacobian-vector products but includes a preconditioner built from an approximate Jacobian matrix . This is generally preferred over `JFNK` for better convergence. -* **`NEWTON`**: Full Newton Solve . This option uses the Jacobian provided by kernels (which may not be exact) for the Krylov solve . It requires an accurate Jacobian for effective convergence . - -The choice between `JFNK`, `PJFNK`, and `NEWTON` depends on the problem's nonlinearity, the cost of forming the Jacobian, and the desired convergence properties. `PJFNK` is often a good balance, providing robustness without the full cost of assembling an exact Jacobian. - -## Key PETSc Options and MOOSE Equivalents - -MOOSE allows users to configure PETSc options through parameters in the `[Executioner]` block . - -* **`-snes_type`**: Controls the type of nonlinear solver. - * MOOSE's `solve_type` parameter maps to this. For example, `solve_type = JFNK` or `solve_type = PJFNK` internally configures the SNES type for matrix-free operation . -* **`-ksp_type`**: Controls the type of Krylov subspace method for the linear solve. - * GMRES is the default in MOOSE . You can set this directly using `petsc_options_iname = '-ksp_type'` and `petsc_options_value = 'gmres'` . -* **`-pc_type`**: Controls the type of preconditioner. - * MOOSE's default preconditioning is block-diagonal . Common options include `ilu` (incomplete LU), `bjacobi` (block Jacobi), `asm` (Additive Schwartz Method), `lu` (full LU), `gamg` (Geometric AMG), and `hypre` (Hypre preconditioners like BoomerAMG) . These can be set via `petsc_options_iname = '-pc_type'` and `petsc_options_value = 'ilu'` (or other types) . - -### MOOSE `[Executioner]` Block Parameters - -` ` `ini -[Executioner] - type = Steady - solve_type = PJFNK # or JFNK, NEWTON, FD, LINEAR - petsc_options_iname = '-snes_type -ksp_type -pc_type -ksp_gmres_restart -pc_asm_overlap' - petsc_options_value = 'newtonls gmres bjacobi 30 2' -[] -` ` ` - -## Convergence Monitors - -MOOSE provides several convergence monitors for both nonlinear and linear solves: - -* **Nonlinear Residual Norm**: MOOSE prints the norm of the nonlinear residual, $\|\vec{R}(\vec{u}_n)\|$, at each Newton iteration . Convergence is typically checked against absolute (`nl_abs_tol`) and relative (`nl_rel_tol`) tolerances . -* **Linear Residual Norm**: For the linear solve within each Newton iteration, MOOSE can print the norm of the linear residual, $\|\vec{\rho}_k\|$, if `print_linear_residuals = true` is set in the `[Outputs]` block . -* **SNES Line Search**: PETSc's SNES line search monitors the step size $\alpha$ in the update $\mathbf{u}^{i} = \mathbf{u}^{i-1} + \alpha \delta \mathbf{u}^{i}$ . The line search type can be controlled by PETSc options like `-snes_linesearch_type` . - -## Classes & Methods - -* `NonlinearSystem::getSNES()`: Retrieves the PETSc SNES object for the nonlinear system . -* `FEProblemBase::computeResidualSys()`: Computes the residual vector for a given system . -* `FEProblemBase::computeJacobianSys()`: Computes the Jacobian matrix for a given system . -* `Moose::ST_JFNK`, `Moose::ST_PJFNK`, `Moose::ST_NEWTON`: Enumerations defining the solve types . - -## Equations - -1. **Newton's Method Linear System**: - $$ - \mathbf{J}(\mathbf{u}^{i-1}) \delta \mathbf{u}^{i} = -\mathbf{R}(\mathbf{u}^{i-1}) - $$ -2. **Matrix-Free Jacobian-Vector Product Approximation**: - $$ - \mathbf{J}(\mathbf{u}^{i-1}) \mathbf{y} \approx \frac{\mathbf{R}(\mathbf{u}^{i-1} + \epsilon \mathbf{y}) - \mathbf{R}(\mathbf{u}^{i-1})}{\epsilon} - $$ -3. **Nonlinear Solution Update**: - $$ - \mathbf{u}^{i} = \mathbf{u}^{i-1} + \alpha \delta \mathbf{u}^{i} - $$ - -## Parameters - -* `solve_type`: `MooseEnum` (`PJFNK`, `JFNK`, `NEWTON`, `FD`, `LINEAR`). Default is `PJFNK`. Controls the general method for - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - - -## Preconditioning strategies in MOOSE - -MOOSE provides several preconditioning strategies to enhance the efficiency of solving nonlinear systems, including Single Matrix Preconditioner (SMP), Finite Difference Preconditioner (FDP), and Physics-Based Preconditioner (PBP) . These strategies can be configured within the `[Preconditioning]` block in the input file or through PETSc options . - -## Preconditioning Strategies - -### 1. Single Matrix Preconditioner (SMP) -The `SingleMatrixPreconditioner` builds a preconditioner using user-defined off-diagonal parts of the Jacobian . By default, for `PJFNK` solves, a block-diagonal preconditioning matrix is used where each block corresponds to a single MOOSE variable, ignoring off-diagonal Jacobian terms . You can specify off-diagonal entries using `off_diag_row` and `off_diag_column` parameters, or group variables using `coupled_groups` to generate off-diagonal Jacobians for all pairs within a group . - -**Classes & Methods:** -* `SingleMatrixPreconditioner::SingleMatrixPreconditioner(const InputParameters & params)`: Constructor that sets up the coupling matrix based on input parameters . -* `SingleMatrixPreconditioner::validParams()`: Defines valid input parameters for SMP, including `coupled_groups`, `off_diag_row`, `off_diag_column`, and `full` . - -**MOOSE Input Syntax:** -` ` `ini -[Preconditioning] - [my_smp] - type = SMP - # Example for coupled_groups - coupled_groups = 'var1,var2 var3,var4' - # Example for off_diag_row and off_diag_column - off_diag_row = 'var1 var2' - off_diag_column = 'var2 var1' - [] -[] -` ` ` - -### 2. Finite Difference Preconditioner (FDP) -The `FiniteDifferencePreconditioner` builds a numerical Jacobian for preconditioning by finite differencing . This method is generally costly and is recommended primarily for testing and verification purposes . It can use either a "standard" finite difference approach or one based on "coloring" . The "standard" finite difference method will add off-diagonal entries to the coupling matrix . - -**Classes & Methods:** -* `FiniteDifferencePreconditioner::FiniteDifferencePreconditioner(const InputParameters & params)`: Constructor that initializes the finite difference type . -* `FiniteDifferencePreconditioner::validParams()`: Defines valid input parameters, including `implicit_geometric_coupling` and `finite_difference_type` . - -**Parameters:** -* `finite_difference_type = "standard" | "coloring"` (type: `MooseEnum`, default: `"coloring"`): Specifies the finite differencing method . - -### 3. Physics-Based Preconditioner (PBP) -The `PhysicsBasedPreconditioner` allows individual physics (variables) to have their own preconditioners . It decomposes the system into smaller linear systems, each corresponding to a variable, and applies a specified preconditioner to each . The order in which these block rows are solved can be specified using `solve_order` . Off-diagonal coupling terms can also be included . PBP must be used with the `JFNK` solve type . - -**Classes & Methods:** -* `PhysicsBasedPreconditioner::PhysicsBasedPreconditioner(const InputParameters & params)`: Constructor that sets up the coupling matrix, preconditioner types, and solve order . -* `PhysicsBasedPreconditioner::addSystem(unsigned int var, std::vector off_diag, libMesh::PreconditionerType type)`: Adds a diagonal system and optionally off-diagonal systems, specifying the type of preconditioning for that system . -* `PhysicsBasedPreconditioner::setup()`: Fills in the preconditioning matrix by computing Jacobian blocks for diagonal and specified off-diagonal terms . -* `PhysicsBasedPreconditioner::apply(const NumericVector & x, NumericVector & y)`: Computes the preconditioned vector by solving the individual systems in the specified order, accounting for off-diagonal couplings . - -**MOOSE Input Syntax:** -` ` `ini -[Preconditioning] - [my_pbp] - type = PBP - solve_order = 'temp pressure' # Example: solve temperature then pressure - preconditioner = 'hypre hypre' # Example: use hypre for both - off_diag_row = 'temp' - off_diag_column = 'pressure' - [] -[] -` ` ` - -### 4. Block Diagonal vs. Block Off-Diagonal Coupling -MOOSE determines coupling between variables through a `CouplingMatrix` . -* **Block Diagonal:** By default, for `PJFNK` solves, the preconditioning matrix is block-diagonal, meaning off-diagonal Jacobian terms are ignored . This is represented by setting 1s on the diagonal of the `CouplingMatrix` and 0s elsewhere . -* **Block Off-Diagonal:** You can explicitly include off-diagonal coupling terms using parameters like `off_diag_row` and `off_diag_column` . These parameters specify which variable pairs should have their Jacobian blocks included in the preconditioning matrix . The `full = true` parameter can be used to include all possible couplings between variables for convenience . - -### 5. Algebraic Multigrid (AMG) with HYPRE BoomerAMG -MOOSE leverages PETSc for solvers and preconditioners, including HYPRE's BoomerAMG . BoomerAMG is an algebraic multigrid method suitable for elliptic PDEs . - -**Configuration through MOOSE:** -You configure HYPRE BoomerAMG using PETSc options, which can be set in the `Executioner` or `Preconditioning` blocks using `petsc_options_iname` and `petsc_options_value` . - -**Parameters:** -* `petsc_options_iname = '-pc_type -pc_hypre_type'` -* `petsc_options_value = 'hypre boomeramg'` - -Key BoomerAMG options include: -* `-pc_hypre_boomeramg_strong_threshold`: Controls the coarsening mechanism by setting a threshold for matrix entries to be kept . Default is 0.25, but 0.7 is automatically set for 3D problems . -* `-pc_hypre_boomeramg_max_levels`: Number of multigrid levels . -* `-pc_hypre_boomeramg_coarsen_type`: Coarsening algorithm, e.g., `Falgout` (default), `HMIS`, or `PMIS` . -* `-pc_hypre_boomeramg_agg_nl`: Number of levels for aggressive coarsening . -* `-pc_hypre_boomeramg_agg_num_paths`: Number of pathways to consider for aggressive coarsening . -* `-pc_hypre_boomeramg_truncfactor`: Truncation factor for interpolation . -* `-pc_hypre_boomeramg_interp_type`: Type of interpolation, e.g., `classic` (default) or `ext+i` . - -**MOOSE Input Syntax:** -` ` `ini -[Executioner] - type = Steady - petsc_options_iname = '-pc_type -pc_hypre_type -pc_hypre_boomeramg_strong_threshold' - petsc_options_value = 'hypre boomeramg 0.7' -[] -` ` ` - -### 6. Automatic Differentiation (AD) and Preconditioning -MOOSE uses forward mode automatic differentiation from the MetaPhysicL package to compute Jacobians . When `ADKernel` is used, the Jacobian is automatically calculated . While AD Jacobians can be slower to compute than hand-coded ones, they parallelize well and can benefit from a `NEWTON` solve type, potentially leading to decreased overall solve time . - -The preconditioner is seldom the exact Jacobian because computing it is computationally expensive and memory-intensive . Even with AD, the preconditioner is an approximation of the Jacobian, not necessarily exact . The `PJFNK` solve type uses a preconditioning matrix that approximates the Jacobian . If the Jacobian is not exact, the Newton update might not effectively reduce the residual, potentially leading to unconverged iterations . - -## Notes -The `FieldSplitPreconditioner` (FSP) is another preconditioner that allows custom preconditioning for each nonlinear variable . It can be used for block-diagonal preconditioning and is the default for `PJFNK` solves . While similar in concept to PBP, FSP is a separate implementation. - -Other preconditioners mentioned in the codebase include `MooseStaticCondensationPreconditioner` and `VariableCondensationPreconditioner` . These are specialized preconditioners for static and variable condensation, respectively. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-mesh-adaptivity.md b/packages/akms/src/akms/_bundled/global_nodes/moose-mesh-adaptivity.md deleted file mode 100644 index 2b1b1ff..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-mesh-adaptivity.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -id: moose-mesh-adaptivity -title: MOOSE Mesh System and Adaptivity -domain: architecture -subdomain: procedural -tags: -- mesh-generator -- AMR -- adaptivity -- displaced-mesh -- partitioning -- subdomain -- sideset -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-object-factory - type: requires - weight: 0.6 - note: Uses MOOSE object factory and registration pattern -- to: tgs-dom-fem - type: implements - weight: 0.7 - note: Mesh generators and AMR provide the FEM discretization infrastructure ---- - -# MOOSE Mesh System and Adaptivity - -Framework knowledge node covering 1 aspect(s) of Mesh System and Adaptivity. - -## Mesh management and adaptivity in MOOSE - -MOOSE manages meshes and mesh adaptivity through a system of `MeshGenerator` objects and an `Adaptivity` system. Mesh generation involves a pipeline of `MeshGenerator`s that can create or modify meshes, allowing for combinatorial mesh construction. Adaptive Mesh Refinement (AMR) is handled by the `Adaptivity` block, which uses various error indicators and relies on `libMesh` for refinement and coarsening operations. Parallel mesh partitioning distributes elements across processors, and named blocks, sidesets, and nodesets are used to restrict physics and boundary conditions. - -## 1. Mesh Generators: `FileMeshGenerator`, `GeneratedMeshGenerator`, `MeshGeneratorMesh` - -MOOSE uses a `MeshGenerator` system to construct meshes, which can involve chaining multiple generators together to build complex geometries . There are two main types of `MeshGenerator`s: those that create a mesh from scratch and those that modify an existing mesh . - -### How the Generator Pipeline Works - -The `MeshGenerator` pipeline works by evaluating and generating individual mesh objects in a dependency-sorted order, forming a Directed Acyclic Graph (DAG) . - -**Classes & Methods:** -* `MeshGeneratorSystem::addMeshGenerator(const std::string & type, const std::string & name, const InputParameters & params)`: Stores parameters for future construction of a `MeshGenerator` . -* `MeshGeneratorSystem::createAddedMeshGenerators()`: Parses input parameters to build the execution tree for generators and constructs them in dependency order . -* `MeshGenerator::generate()`: The core method overridden by child classes to create or modify the mesh . -* `MeshGenerator::generateInternal()`: An internal method called by `MooseApp` to execute the `MeshGenerator`, handling data generation and output . - -**Algorithm Steps:** -` ` `pseudocode -1. User defines MeshGenerator blocks in the input file. -2. MooseApp collects all MeshGenerator parameters. -3. MeshGeneratorSystem builds a dependency graph of MeshGenerators. -4. MeshGenerators are constructed and executed in dependency order. -5. For each MeshGenerator: - a. If it creates a mesh (e.g., GeneratedMeshGenerator, FileMeshGenerator), it calls buildMeshBaseObject(), buildReplicatedMesh(), or buildDistributedMesh(). - b. If it modifies a mesh (e.g., TiledMeshGenerator, RefineBlockGenerator), it obtains an input mesh using getMesh() or getMeshByName(). - c. The generate() method is called to produce the output mesh. - d. The output mesh can be used as input for subsequent MeshGenerators. -6. The final mesh is used for the simulation. -` ` ` - -**MOOSE Input Syntax:** -` ` `ini -[Mesh] - [gmg] - type = GeneratedMeshGenerator - dim = 3 - nx = 3 - ny = 3 - nz = 3 - [] - - [tmg] - type = TiledMeshGenerator - input = gmg # 'tmg' uses the output of 'gmg' as its input - x_tiles = 2 - y_tiles = 1 - z_tiles = 5 - [] -[] -` ` ` - -## 2. Mesh Modifiers/Generators Chaining: Combinatorial Mesh Construction - -MOOSE allows for combinatorial mesh construction by chaining `MeshGenerator`s. This means the output of one generator can serve as the input for another, enabling the creation of complex meshes from simpler operations . - -**Classes & Methods:** -* `MeshGenerator::getMesh()`: Retrieves the mesh from a previous generator . -* `MeshGenerator::getMeshByName()`: Retrieves a mesh by its name from a previous generator . -* `CombinerGenerator`: Collects multiple meshes into a single, unconnected mesh . -* `RefineBlockGenerator`: Refines one or more blocks within an existing mesh . - -**MOOSE Input Syntax:** -An example of chaining is shown in the previous section with `GeneratedMeshGenerator` and `TiledMeshGenerator` . Another example involves combining meshes: -` ` `ini -[Mesh] - [block_one] - type = GeneratedMeshGenerator - dim = 3 - nx = 4 - ny = 4 - nz = 4 - # ... other parameters ... - [] - [block_two] - type = GeneratedMeshGenerator - dim = 3 - nx = 9 - ny = 9 - nz = 4 - # ... other parameters ... - [] - [block_one_id] - type = SubdomainIDGenerator - input = block_one - subdomain_id = 1 - [] - [block_two_id] - type = SubdomainIDGenerator - input = block_two - subdomain_id = 2 - [] - [combine] - type = MeshCollectionGenerator - inputs = ' block_one_id block_two_id' - [] -[] -` ` ` - -## 3. Adaptive Mesh Refinement (AMR): `Adaptivity` block - -The `Adaptivity` system in MOOSE handles Adaptive Mesh Refinement (AMR) . It allows for dynamic refinement and coarsening of the mesh based on error indicators. - -**Classes & Methods:** -* `Adaptivity`: The main class responsible for managing mesh adaptivity . It initializes and controls the adaptivity cycles . -* `Adaptivity::setErrorEstimator(const MooseEnum & error_estimator_name)`: Sets the error estimator to be used for adaptivity . - -**Parameters:** -* `Adaptivity/initial_steps`: Number of adaptivity cycles to perform before the simulation starts . -* `Adaptivity/steps`: Number of adaptivity cycles to run during a steady solve . -* `Adaptivity/p_refinement`: Indicates whether the refinement will be p-refinement or h-refinement . - -**Error Indicators Available:** -MOOSE leverages `libMesh` for error estimation. The `Adaptivity::setErrorEstimator` method indicates support for: -* `Laplacian` -* `Kelly` (e.g., `libmesh::KellyErrorEstimator`) -* `PatchRecovery` (e.g., `libmesh::PatchRecoveryErrorEstimator`) -* `Fourth` (e.g., `libmesh::FourthErrorEstimators`) - -**MOOSE Input Syntax:** -` ` `ini -[Adaptivity] - # ... configuration for adaptivity ... -[] -` ` ` - -## 4. How Refinement/Coarsening Works: `libMesh` Classes - -MOOSE utilizes `libMesh` for the underlying mesh data structures and refinement/coarsening algorithms . The `Adaptivity` class interacts with `libMesh::MeshRefinement` to perform these operations. - -**Classes & Methods:** -* `libMesh::MeshRefinement`: A `libMesh` class that handles the actual mesh refinement and coarsening operations . -* `libMesh::ErrorEstimator`: Base class for error estimators in `libMesh` . -* `libMesh::SystemNorm`: Used to define the error norm for adaptivity . - -## 5. Mesh Partitioning for Parallel - -MOOSE supports parallel computation by partitioning the mesh across multiple processors. - -**Classes & Methods:** -* `MooseMesh::determineUseDistributedMesh()`: Determines whether to use a distributed mesh . -* `MooseMesh::partitioning()`: Returns MOOSE Mesh partitioning options . - -**Parameters:** -* `Mesh/parallel_type = DEFAULT | REPLICATED | DISTRIBUTED`: Controls how the mesh is distributed. - * `DEFAULT`: Uses `libMesh::ReplicatedMesh` unless `--distributed-mesh` is specified . - * `REPLICATED`: Always uses `libMesh::ReplicatedMesh` . - * `DISTRIBUTED`: Always uses `libMesh::DistributedMesh` . -* `Mesh/partitioner = ...`: Specifies a mesh partitioner to use when splitting the mesh for parallel computation . Available partitioners include `linear_partitioner`, `centroid_partitioner`, `parmetis_partitioner`, `hilbert_sfc_partitioner`, and `morton_sfc_partitioner` . -* `Mesh/centroid_partitioner_direction = x | y | z | radial`: Specifies the sort direction if using the centroid partitioner . - -## 6. Displaced Mesh: `use_displaced_mesh` - -MOOSE handles geometric nonlinearity through the concept of a displaced mesh. This is typically managed by a `DisplacedProblem` which uses a `MooseMesh` that can be cloned and modified to represent the deformed geometry. - -**Classes & Methods:** -* `DisplacedProblem`: A specialized problem type that handles displaced meshes . -* `MooseMesh::clone()`: Creates a copy of the mesh, which can then be displaced . -* `MooseMesh::safeClone()`: A safer version of `clone()` that returns a `std::unique_ptr` . - -## 7. Named Blocks (Subdomains), Sidesets, Nodesets - -Named blocks (subdomains), sidesets, and nodesets are crucial for defining regions where specific kernels, boundary conditions (BCs), and materials apply. - -**Classes & Methods:** -* `MooseMesh`: Stores the underlying `libMesh` mesh, which contains information about subdomains, sidesets, and nodesets . -* `MooseMesh::construct_node_list_from_side_list`: A parameter that controls whether nodesets are automatically constructed from sidesets . -* `MooseMesh::displace_node_list_by_side_list`: Controls renumbering of existing nodesets when constructing nodesets from sidesets . - -**Usage for Restricting Kernels/BCs:** -* **Subdomains (Blocks):** Elements are grouped into subdomains, allowing kernels, materials, and initial conditions to be applied only to specific regions of the mesh . -* **Sidesets:** Collections of $dim-1$ dimensional elements (faces in 3D, edges in 2D) typically on boundaries. These are used to apply boundary conditions or other boundary-related objects . -* **Nodesets:** Collections of nodes, typically on a boundary - -Wiki pages you might want to explore: -- [MOOSE Framework Overview (idaholab/moose)](https://deepwiki.com/idaholab/moose#1) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-mesh-amr.md b/packages/akms/src/akms/_bundled/global_nodes/moose-mesh-amr.md deleted file mode 100644 index 7b0efb5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-mesh-amr.md +++ /dev/null @@ -1,204 +0,0 @@ ---- -id: moose-mesh-amr -title: MOOSE Mesh management and adaptivity in MOOSE -domain: architecture -subdomain: procedural -tags: -- mesh-generator -- AMR -- adaptivity -- displaced-mesh -- partitioning -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-mesh-adaptivity - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-mesh-adaptivity ---- - -# MOOSE Mesh management and adaptivity in MOOSE - -MOOSE manages meshes and mesh adaptivity through a system of `MeshGenerator` objects and an `Adaptivity` system. Mesh generation involves a pipeline of `MeshGenerator`s that can create or modify meshes, allowing for combinatorial mesh construction. Adaptive Mesh Refinement (AMR) is handled by the `Adaptivity` block, which uses various error indicators and relies on `libMesh` for refinement and coarsening operations. Parallel mesh partitioning distributes elements across processors, and named blocks, sidesets, and nodesets are used to restrict physics and boundary conditions. - -## 1. Mesh Generators: `FileMeshGenerator`, `GeneratedMeshGenerator`, `MeshGeneratorMesh` - -MOOSE uses a `MeshGenerator` system to construct meshes, which can involve chaining multiple generators together to build complex geometries . There are two main types of `MeshGenerator`s: those that create a mesh from scratch and those that modify an existing mesh . - -### How the Generator Pipeline Works - -The `MeshGenerator` pipeline works by evaluating and generating individual mesh objects in a dependency-sorted order, forming a Directed Acyclic Graph (DAG) . - -**Classes & Methods:** -* `MeshGeneratorSystem::addMeshGenerator(const std::string & type, const std::string & name, const InputParameters & params)`: Stores parameters for future construction of a `MeshGenerator` . -* `MeshGeneratorSystem::createAddedMeshGenerators()`: Parses input parameters to build the execution tree for generators and constructs them in dependency order . -* `MeshGenerator::generate()`: The core method overridden by child classes to create or modify the mesh . -* `MeshGenerator::generateInternal()`: An internal method called by `MooseApp` to execute the `MeshGenerator`, handling data generation and output . - -**Algorithm Steps:** -` ` `pseudocode -1. User defines MeshGenerator blocks in the input file. -2. MooseApp collects all MeshGenerator parameters. -3. MeshGeneratorSystem builds a dependency graph of MeshGenerators. -4. MeshGenerators are constructed and executed in dependency order. -5. For each MeshGenerator: - a. If it creates a mesh (e.g., GeneratedMeshGenerator, FileMeshGenerator), it calls buildMeshBaseObject(), buildReplicatedMesh(), or buildDistributedMesh(). - b. If it modifies a mesh (e.g., TiledMeshGenerator, RefineBlockGenerator), it obtains an input mesh using getMesh() or getMeshByName(). - c. The generate() method is called to produce the output mesh. - d. The output mesh can be used as input for subsequent MeshGenerators. -6. The final mesh is used for the simulation. -` ` ` - -**MOOSE Input Syntax:** -` ` `ini -[Mesh] - [gmg] - type = GeneratedMeshGenerator - dim = 3 - nx = 3 - ny = 3 - nz = 3 - [] - - [tmg] - type = TiledMeshGenerator - input = gmg # 'tmg' uses the output of 'gmg' as its input - x_tiles = 2 - y_tiles = 1 - z_tiles = 5 - [] -[] -` ` ` - -## 2. Mesh Modifiers/Generators Chaining: Combinatorial Mesh Construction - -MOOSE allows for combinatorial mesh construction by chaining `MeshGenerator`s. This means the output of one generator can serve as the input for another, enabling the creation of complex meshes from simpler operations . - -**Classes & Methods:** -* `MeshGenerator::getMesh()`: Retrieves the mesh from a previous generator . -* `MeshGenerator::getMeshByName()`: Retrieves a mesh by its name from a previous generator . -* `CombinerGenerator`: Collects multiple meshes into a single, unconnected mesh . -* `RefineBlockGenerator`: Refines one or more blocks within an existing mesh . - -**MOOSE Input Syntax:** -An example of chaining is shown in the previous section with `GeneratedMeshGenerator` and `TiledMeshGenerator` . Another example involves combining meshes: -` ` `ini -[Mesh] - [block_one] - type = GeneratedMeshGenerator - dim = 3 - nx = 4 - ny = 4 - nz = 4 - # ... other parameters ... - [] - [block_two] - type = GeneratedMeshGenerator - dim = 3 - nx = 9 - ny = 9 - nz = 4 - # ... other parameters ... - [] - [block_one_id] - type = SubdomainIDGenerator - input = block_one - subdomain_id = 1 - [] - [block_two_id] - type = SubdomainIDGenerator - input = block_two - subdomain_id = 2 - [] - [combine] - type = MeshCollectionGenerator - inputs = ' block_one_id block_two_id' - [] -[] -` ` ` - -## 3. Adaptive Mesh Refinement (AMR): `Adaptivity` block - -The `Adaptivity` system in MOOSE handles Adaptive Mesh Refinement (AMR) . It allows for dynamic refinement and coarsening of the mesh based on error indicators. - -**Classes & Methods:** -* `Adaptivity`: The main class responsible for managing mesh adaptivity . It initializes and controls the adaptivity cycles . -* `Adaptivity::setErrorEstimator(const MooseEnum & error_estimator_name)`: Sets the error estimator to be used for adaptivity . - -**Parameters:** -* `Adaptivity/initial_steps`: Number of adaptivity cycles to perform before the simulation starts . -* `Adaptivity/steps`: Number of adaptivity cycles to run during a steady solve . -* `Adaptivity/p_refinement`: Indicates whether the refinement will be p-refinement or h-refinement . - -**Error Indicators Available:** -MOOSE leverages `libMesh` for error estimation. The `Adaptivity::setErrorEstimator` method indicates support for: -* `Laplacian` -* `Kelly` (e.g., `libmesh::KellyErrorEstimator`) -* `PatchRecovery` (e.g., `libmesh::PatchRecoveryErrorEstimator`) -* `Fourth` (e.g., `libmesh::FourthErrorEstimators`) - -**MOOSE Input Syntax:** -` ` `ini -[Adaptivity] - # ... configuration for adaptivity ... -[] -` ` ` - -## 4. How Refinement/Coarsening Works: `libMesh` Classes - -MOOSE utilizes `libMesh` for the underlying mesh data structures and refinement/coarsening algorithms . The `Adaptivity` class interacts with `libMesh::MeshRefinement` to perform these operations. - -**Classes & Methods:** -* `libMesh::MeshRefinement`: A `libMesh` class that handles the actual mesh refinement and coarsening operations . -* `libMesh::ErrorEstimator`: Base class for error estimators in `libMesh` . -* `libMesh::SystemNorm`: Used to define the error norm for adaptivity . - -## 5. Mesh Partitioning for Parallel - -MOOSE supports parallel computation by partitioning the mesh across multiple processors. - -**Classes & Methods:** -* `MooseMesh::determineUseDistributedMesh()`: Determines whether to use a distributed mesh . -* `MooseMesh::partitioning()`: Returns MOOSE Mesh partitioning options . - -**Parameters:** -* `Mesh/parallel_type = DEFAULT | REPLICATED | DISTRIBUTED`: Controls how the mesh is distributed. - * `DEFAULT`: Uses `libMesh::ReplicatedMesh` unless `--distributed-mesh` is specified . - * `REPLICATED`: Always uses `libMesh::ReplicatedMesh` . - * `DISTRIBUTED`: Always uses `libMesh::DistributedMesh` . -* `Mesh/partitioner = ...`: Specifies a mesh partitioner to use when splitting the mesh for parallel computation . Available partitioners include `linear_partitioner`, `centroid_partitioner`, `parmetis_partitioner`, `hilbert_sfc_partitioner`, and `morton_sfc_partitioner` . -* `Mesh/centroid_partitioner_direction = x | y | z | radial`: Specifies the sort direction if using the centroid partitioner . - -## 6. Displaced Mesh: `use_displaced_mesh` - -MOOSE handles geometric nonlinearity through the concept of a displaced mesh. This is typically managed by a `DisplacedProblem` which uses a `MooseMesh` that can be cloned and modified to represent the deformed geometry. - -**Classes & Methods:** -* `DisplacedProblem`: A specialized problem type that handles displaced meshes . -* `MooseMesh::clone()`: Creates a copy of the mesh, which can then be displaced . -* `MooseMesh::safeClone()`: A safer version of `clone()` that returns a `std::unique_ptr` . - -## 7. Named Blocks (Subdomains), Sidesets, Nodesets - -Named blocks (subdomains), sidesets, and nodesets are crucial for defining regions where specific kernels, boundary conditions (BCs), and materials apply. - -**Classes & Methods:** -* `MooseMesh`: Stores the underlying `libMesh` mesh, which contains information about subdomains, sidesets, and nodesets . -* `MooseMesh::construct_node_list_from_side_list`: A parameter that controls whether nodesets are automatically constructed from sidesets . -* `MooseMesh::displace_node_list_by_side_list`: Controls renumbering of existing nodesets when constructing nodesets from sidesets . - -**Usage for Restricting Kernels/BCs:** -* **Subdomains (Blocks):** Elements are grouped into subdomains, allowing kernels, materials, and initial conditions to be applied only to specific regions of the mesh . -* **Sidesets:** Collections of $dim-1$ dimensional elements (faces in 3D, edges in 2D) typically on boundaries. These are used to apply boundary conditions or other boundary-related objects . -* **Nodesets:** Collections of nodes, typically on a boundary - -Wiki pages you might want to explore: -- [MOOSE Framework Overview (idaholab/moose)](https://deepwiki.com/idaholab/moose#1) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-multi-phase-component.md b/packages/akms/src/akms/_bundled/global_nodes/moose-multi-phase-component.md deleted file mode 100644 index 9f18acb..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-multi-phase-component.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -id: moose-multi-phase-component -title: MOOSE Multi-Phase Multi-Component Phase Field -domain: phase-field -subdomain: algorithmic -tags: -- multi-phase -- multi-component -- switching-function -- grain-tracker -- cahn-hilliard -- split-CH -- barrier-function -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-derivative-parsed-material - type: requires - weight: 0.6 - note: Uses DerivativeParsedMaterial for free energy definitions -- to: moose-allen-cahn-cahn-hilliard - type: requires - weight: 0.8 - note: Multi-phase uses AC for non-conserved, CH for conserved -- to: cm-phase-field-fracture - type: implements - weight: 0.4 - note: Multi-phase infrastructure shared with phase field fracture models ---- - -# MOOSE Multi-Phase Multi-Component Phase Field - -Framework knowledge node covering 2 aspect(s) of Multi-Phase Multi-Component Phase Field. - -## Multi-phase field models in MOOSE - -MOOSE handles multi-phase field problems by employing multiple order parameters, specialized interpolation functions, and various constraint enforcement mechanisms. It supports an arbitrary number of phases and grains through a flexible material and kernel system. - -## 1. Multiple Order Parameters ($\eta_1, \eta_2, ..., \eta_n$) -MOOSE uses multiple order parameters, typically one per phase or per grain, to represent different phases or grains in a multi-phase system . For grain growth models, the evolution of each grain's order parameter is defined by the Allen-Cahn equation . - -## 2. Interpolation Functions $h(\eta)$ and $g(\eta_1,...,\eta_n)$ -MOOSE constructs multi-phase interpolation using switching functions, denoted as $h(\eta)$, and barrier functions, denoted as $g(\eta)$. - -### Switching Functions $h(\eta)$ -The `SwitchingFunctionMultiPhaseMaterial` class calculates a switching function for a given phase in a multi-phase, multi-order parameter system . The formulation for phase $\alpha$ is given by: -$$ h_\alpha = \frac{\sum_i \eta_{\alpha i}^2}{\sum_\rho \sum_i \eta_{\rho i}^2} $$ -where $i$ indexes grains of a phase and $\rho$ indexes phases . - -For three-phase systems, the `SwitchingFunction3PhaseMaterial` provides a specific switching function to prevent the formation of a third phase at a two-phase interface . The formula is: -$$ h_i = \frac{\eta_i^2}{4} [15 (1-\eta_i) [1 + \eta_i - (\eta_k - \eta_j)^2] + \eta_i (9\eta_i^2 - 5)] $$ -This can also be constrained to the range $[0,1]$ . - -### Barrier Functions $g(\eta_1,...,\eta_n)$ -The `MultiBarrierFunctionMaterial` provides a double-well phase transformation barrier free energy contribution . A common form is: -$$ g(\vec\eta) = \sum_i \eta_i^2(1-\eta_i)^2 $$ . This material can be configured with different polynomial orders for the barrier function . - -## 3. `SwitchingFunctionMaterial` - Available Switching Functions -MOOSE provides several switching functions: -* `SwitchingFunctionMultiPhaseMaterial`: A general switching function for multi-phase, multi-order parameter systems, based on Moelans, Acta Mat., v 59, p.1077-1086 (2011) . -* `SwitchingFunction3PhaseMaterial`: Specifically designed for three-phase systems to suppress the formation of a third phase at two-phase interfaces . -* `MixedSwitchingFunctionMaterial`: Supports mixed switching functions with adjustable weights . - -## 4. Multi-well Potentials: Barrier Function Extension to N Phases -The barrier function is extended to N phases through classes like `MultiBarrierFunctionMaterial` . This material takes a vector of order parameters (`etas`) and computes a barrier function, typically a sum of individual well functions for each order parameter . The `g_order` parameter allows specifying the polynomial order of the switching function . - -## 5. Constraint Enforcement: $\sum_i \eta_i = 1$ -MOOSE enforces the constraint $\sum_i \eta_i = 1$ primarily through a Lagrange multiplier approach . - -### Lagrange Multiplier -The `SwitchingFunctionConstraintLagrange` kernel is used to constrain the sum of all switching functions in a multiphase system . It acts on a Lagrange multiplier variable (`lambda`) . The residual for this kernel is calculated as: -$$ \mathcal{R} = \psi_m \left( \sum_{i=0}^{N-1} h_i - 1 - \epsilon \lambda \right) $$ -where $h_i$ are the switching functions, $\lambda$ is the Lagrange multiplier, and $\epsilon$ is a shift factor to avoid a zero pivot . - -### Penalty Method -A penalty-based constraint is also available for keeping the sum of all phase order parameters equal to one . - -## 6. `GrainTracker` UserObject -The `GrainTracker` UserObject identifies and tracks individual grains . The provided context does not contain details on its internal mechanism for identification and tracking. - -## 7. Phase-Specific Material Properties -MOOSE weights phase-specific material properties by phase fraction using switching functions. For instance, in the KKS multi-phase model, the global concentration `c` is a weighted sum of phase concentrations `c_i` using switching functions `h_i` : -$$ c = h_1(\eta_1,\eta_2,\eta_3,...) c_1 + h_2(\eta_1,\eta_2,\eta_3,...) c_2 + h_3(\eta_1,\eta_2,\eta_3,..) c_3 + ... $$ . - -The `DerivativeMultiPhaseMaterial` combines an arbitrary number of phase free energies into a global free energy using switching functions . The derivative of the total free energy with respect to an order parameter $\eta_i$ involves the switching function and the phase-specific free energy . - -## Classes & Methods - -* `SwitchingFunctionMultiPhaseMaterialTempl::validParams()`: Defines valid parameters for the multi-phase switching function material . -* `SwitchingFunctionMultiPhaseMaterialTempl::SwitchingFunctionMultiPhaseMaterialTempl()`: Constructor for the multi-phase switching function material, initializing properties and derivatives . -* `SwitchingFunction3PhaseMaterial::validParams()`: Defines valid parameters for the three-phase switching function material . -* `SwitchingFunction3PhaseMaterial::SwitchingFunction3PhaseMaterial()`: Constructor for the three-phase switching function material, parsing the switching function expression . -* `MultiBarrierFunctionMaterial::validParams()`: Defines valid parameters for the multi-barrier function material . -* `MultiBarrierFunctionMaterial::MultiBarrierFunctionMaterial()`: Constructor for the multi-barrier function material, initializing properties and derivatives . -* `MultiBarrierFunctionMaterial::computeQpProperties()`: Computes the barrier function value at quadrature points . -* `SwitchingFunctionConstraintLagrange::validParams()`: Defines valid parameters for the Lagrange multiplier constraint kernel . -* `SwitchingFunctionConstraintLagrange::computeQpResidual()`: Computes the residual for the Lagrange multiplier constraint . -* `KKSMultiPhaseConcentration::validParams()`: Defines valid parameters for the KKS multi-phase concentration kernel . -* `DerivativeMultiPhaseBase::validParams()`: Defines valid parameters for the base class for multi-phase derivative materials . -* `DerivativeMultiPhaseMaterial::computeDF()`: Computes the first derivative of the total free energy with respect to a variable . - -## Equations - -### Switching Function for Multi-Phase Systems -For phase $\alpha$, the switching function is: -$$ h_\alpha = \frac{\sum_i \eta_{\alpha i}^2}{\sum_\rho \sum_i \eta_{\rho i}^2} $$ -where $i$ indexes grains of a phase and $\rho$ indexes phases . - -### Switching Function for Three-Phase Systems -The switching function for three phases is: -$$ h_i = \frac{\eta_i^2}{4} [15 (1-\eta_i) [1 + \eta_i - (\eta_k - \eta_j)^2] + \eta_i (9\eta_i^2 - 5)] $$ . - -### Multi-Well Barrier Function -A common form for the multi-well barrier function is: -$$ g(\vec\eta) = \sum_i \eta_i^2(1-\eta_i)^2 $$ . - -### KKS Multi-Phase Concentration -The global concentration $c$ is related to phase concentrations $c_i$ and switching functions $h_i$ by: -$$ c = h_1(\eta_1,\eta_2,\eta_3,...) c_1 + h_2(\eta_1,\eta_2,\eta_3,...) c_2 + h_3(\eta_1,\eta_2,\eta_3,..) c_3 + ... $$ . - -### Allen-Cahn Equation for Grain Growth -The evolution of each grain's order parameter $\eta_i$ is defined by the Allen-Cahn equation: -$$ \frac{\partial \eta_i}{\partial t} = - L \frac{\delta F}{\delta \eta_i} $$ -where $F$ is the free energy functional and $L$ is the order parameter mobility . - -## Parameters - -* `SwitchingFunctionMultiPhaseMaterial`: - * `h_name`: Name of the switching function material property for the given phase (MaterialPropertyName, required) . - * `phase_etas`: Vector of order parameters for the given phase (CoupledVar, required) . - * `all_etas`: Vector of all order parameters for all phases (CoupledVar, required) . -* `SwitchingFunction3PhaseMaterial`: - * `eta_i`: Order parameter i (CoupledVar, required) . - * `eta_j`: Order parameter j (CoupledVar, required) - - -## Multi-component (multi-species) phase field - -ERROR: Request timed out after 120.0s - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-multiapp-coupling.md b/packages/akms/src/akms/_bundled/global_nodes/moose-multiapp-coupling.md deleted file mode 100644 index 907f266..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-multiapp-coupling.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: moose-multiapp-coupling -title: MOOSE MultiApp system for multi-physics coupling -domain: architecture -subdomain: procedural -tags: -- multi-app -- transfer -- picard-iteration -- sub-cycling -- multi-physics -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-multiapp-transfers - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-multiapp-transfers ---- - -# MOOSE MultiApp system for multi-physics coupling - -MOOSE's MultiApp system enables hierarchical coupling of multiple physics simulations, allowing a parent application to launch and control child applications, manage data transfer, and coordinate execution strategies . This system supports various coupling schemes, including loose coupling, Picard iteration, and sub-cycling, with flexible control over execution timing and parallel distribution . - -## Parent-Child App Hierarchy -A parent app launches and controls child apps by defining `MultiApp` objects in its input file . Each `MultiApp` object can represent multiple sub-applications, which are instances of `MooseApp` or derived applications . The parent app passes parameters and input files to the child apps . The hierarchy can be arbitrarily deep, with sub-apps themselves containing `MultiApps` . - -**Parameters:** -* `app_type`: `string` - The name of the `MooseApp` derived application to be executed . -* `input_files`: `string` - Specifies the input file(s) for the sub-app(s) . If one file is provided, it's used for all sub-apps in the `MultiApp` . -* `positions`: `vector` - A list of 3D coordinate vectors defining the offset of each sub-app relative to the parent app's coordinate system . -* `positions_file`: `string` - A file containing position vectors for sub-apps . -* `positions_objects`: `vector` - A list of names of `Positions` objects to specify sub-app locations . -* `clone_parent_mesh`: `bool` - Allows re-using the main application mesh in the sub-app to avoid mesh creation operations . - -**MOOSE Input Syntax:** -` ` `ini -[MultiApps] - [sub_app_name] - type = TransientMultiApp - app_type = MyChildApp - input_files = 'child.i' - positions = '0 0 0' - execute_on = 'timestep_end' - [] -[] -` ` ` - -## `TransientMultiApp` and `FullSolveMultiApp` Execution Strategies - -MOOSE provides different `MultiApp` types to manage how child applications execute. - -### `TransientMultiApp` -The `TransientMultiApp` is designed for sub-applications that progress in time with the main application . It requires sub-apps to use an `Executioner` derived from `Transient` . By default, the time step size for both parent and child apps is the minimum of all requested time steps . It supports sub-cycling, where child apps can take multiple smaller time steps per parent time step . - -**Classes & Methods:** -* `TransientMultiApp::solveStep(Real dt, Real target_time, bool auto_advance = true)`: Solves the sub-app for a given time step `dt` up to `target_time` . -* `TransientMultiApp::incrementTStep(Real target_time)`: Advances the multi-app's time step . -* `TransientMultiApp::finishStep(bool recurse_through_multiapp_levels = false)`: Calls the sub-app's executioner's `endStep` and `postStep` methods . - -**Parameters:** -* `sub_cycling`: `bool`, default: `false` - Allows the `MultiApp` to take smaller timesteps than the rest of the simulation . -* `interpolate_transfers`: `bool`, default: `false` - When `sub_cycling` is enabled, allows transferred values to be interpolated over the time frame the `MultiApp` is executing . -* `detect_steady_state`: `bool`, default: `false` - If true and sub-cycling, a steady-state check is performed for each child app, allowing them to skip to the end of the parent time step if steady conditions are detected . -* `output_sub_cycles`: `bool`, default: `false` - If true, every sub-cycle will be output . - -### `FullSolveMultiApp` -The `FullSolveMultiApp` performs a complete simulation during each execution . This is often used for steady-state fixed-point iterations . - -**Parameters:** -* `ignore_solve_not_converge`: `bool`, default: `false` - If true, the main app continues even if a sub-app's solve does not converge . - -## Data Transfer: `MultiAppTransfer` Base Class -Transfers are used to move information between applications in the MultiApp hierarchy . The `MultiAppTransfer` is the base class for these operations. Data can be transferred to and from `AuxiliaryVariable` fields, `Postprocessor` values, and `UserObject`s . - -**Classes & Methods:** -* `MultiAppTransfer`: Base class for all MultiApp transfer objects . - -**Transfer Types:** -* `MultiAppGeneralFieldShapeEvaluationTransfer`: Interpolates a field (solution or auxiliary) from one domain to another, populating an `AuxiliaryVariable` field in the receiving app . This is a more general and efficient implementation of field interpolation . - * **Parameters:** `from_multi_app`, `to_multi_app`, `source_variable`, `variable` . -* `MultiAppGeneralFieldNearestLocationTransfer`: Moves field data by matching nodes/centroids . -* `MultiAppGeneralFieldUserObjectTransfer`: Evaluates a "spatial" `UserObject` in one app at the other app's nodes/centroids and deposits the information into an `AuxiliaryVariable` field . -* `MultiAppPostprocessorTransfer`: Moves `Postprocessor` data from one app to another . - -**MOOSE Input Syntax (Example `MultiAppPostprocessorTransfer`):** -` ` `ini -[Transfers] - [pressure_drop_transfer] - type = MultiAppPostprocessorTransfer - from_multi_app = subchannel - from_postprocessor = total_pressure_drop_SC - to_postprocessor = core_delta_p_tgt - reduction_type = average - execute_on = 'timestep_end' - [] -[] -` ` ` - -## Execution Timing: `execute_on` -The `execute_on` parameter, inherited from `SetupInterface`, dictates when an object, including `MultiApp`s and `Transfers`, is executed during the simulation . This parameter controls the coupling scheme (explicit vs. implicit). - -**Parameters:** -* `execute_on`: `enum` - Controls when the `MultiApp` or `Transfer` is executed. - * `TIMESTEP_BEGIN`: Executed prior to the solve for each time step . - * `TIMESTEP_END`: Executed after the solve for each time step . - * `NONLINEAR`: Executed prior to each Jacobian evaluation . - * `MULTIAPP_FIXED_POINT_BEGIN`: Executed at the beginning of each fixed-point solve loop . - * `MULTIAPP_FIXED_POINT_END`: Executed at the end of each fixed-point solve loop . - * Other flags exist for various execution points . - -**Coupling Scheme Control:** -* **Explicit (Loose) Coupling:** If `MultiApp`s and `Transfers` are executed only once per time step (e.g., `TIMESTEP_END`), data is exchanged once, and the simulation proceeds . -* **Implicit (Tight) Coupling / Picard Iteration:** By setting `fixed_point_max_its` in the parent app's `Executioner` block to a value greater than 1, MOOSE performs Picard iterations, where data is exchanged and physics re-solved until convergence within a time step . - -## Picard Iteration -MOOSE performs fixed-point (Picard) iteration between parent and child apps to achieve tight coupling . This involves iterating back - -Wiki pages you might want to explore: -- [MOOSE Framework Overview (idaholab/moose)](https://deepwiki.com/idaholab/moose#1) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-multiapp-transfers.md b/packages/akms/src/akms/_bundled/global_nodes/moose-multiapp-transfers.md deleted file mode 100644 index 7f7b427..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-multiapp-transfers.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: moose-multiapp-transfers -title: MOOSE MultiApp and Transfers — Multi-Physics Coupling -domain: architecture -subdomain: procedural -tags: -- multi-app -- transfer -- picard-iteration -- sub-cycling -- multi-physics -- parent-child -- field-interpolation -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-object-factory - type: requires - weight: 0.6 - note: Uses MOOSE object factory and registration pattern -- to: moose-mesh-adaptivity - type: requires - weight: 0.5 - note: Transfers operate on mesh fields -- to: tgs-dom-fem - type: implements - weight: 0.5 - note: MultiApp couples separate FEM solves via field transfers ---- - -# MOOSE MultiApp and Transfers — Multi-Physics Coupling - -Framework knowledge node covering 1 aspect(s) of MultiApp and Transfers — Multi-Physics Coupling. - -## MultiApp system for multi-physics coupling - -MOOSE's MultiApp system enables hierarchical coupling of multiple physics simulations, allowing a parent application to launch and control child applications, manage data transfer, and coordinate execution strategies . This system supports various coupling schemes, including loose coupling, Picard iteration, and sub-cycling, with flexible control over execution timing and parallel distribution . - -## Parent-Child App Hierarchy -A parent app launches and controls child apps by defining `MultiApp` objects in its input file . Each `MultiApp` object can represent multiple sub-applications, which are instances of `MooseApp` or derived applications . The parent app passes parameters and input files to the child apps . The hierarchy can be arbitrarily deep, with sub-apps themselves containing `MultiApps` . - -**Parameters:** -* `app_type`: `string` - The name of the `MooseApp` derived application to be executed . -* `input_files`: `string` - Specifies the input file(s) for the sub-app(s) . If one file is provided, it's used for all sub-apps in the `MultiApp` . -* `positions`: `vector` - A list of 3D coordinate vectors defining the offset of each sub-app relative to the parent app's coordinate system . -* `positions_file`: `string` - A file containing position vectors for sub-apps . -* `positions_objects`: `vector` - A list of names of `Positions` objects to specify sub-app locations . -* `clone_parent_mesh`: `bool` - Allows re-using the main application mesh in the sub-app to avoid mesh creation operations . - -**MOOSE Input Syntax:** -` ` `ini -[MultiApps] - [sub_app_name] - type = TransientMultiApp - app_type = MyChildApp - input_files = 'child.i' - positions = '0 0 0' - execute_on = 'timestep_end' - [] -[] -` ` ` - -## `TransientMultiApp` and `FullSolveMultiApp` Execution Strategies - -MOOSE provides different `MultiApp` types to manage how child applications execute. - -### `TransientMultiApp` -The `TransientMultiApp` is designed for sub-applications that progress in time with the main application . It requires sub-apps to use an `Executioner` derived from `Transient` . By default, the time step size for both parent and child apps is the minimum of all requested time steps . It supports sub-cycling, where child apps can take multiple smaller time steps per parent time step . - -**Classes & Methods:** -* `TransientMultiApp::solveStep(Real dt, Real target_time, bool auto_advance = true)`: Solves the sub-app for a given time step `dt` up to `target_time` . -* `TransientMultiApp::incrementTStep(Real target_time)`: Advances the multi-app's time step . -* `TransientMultiApp::finishStep(bool recurse_through_multiapp_levels = false)`: Calls the sub-app's executioner's `endStep` and `postStep` methods . - -**Parameters:** -* `sub_cycling`: `bool`, default: `false` - Allows the `MultiApp` to take smaller timesteps than the rest of the simulation . -* `interpolate_transfers`: `bool`, default: `false` - When `sub_cycling` is enabled, allows transferred values to be interpolated over the time frame the `MultiApp` is executing . -* `detect_steady_state`: `bool`, default: `false` - If true and sub-cycling, a steady-state check is performed for each child app, allowing them to skip to the end of the parent time step if steady conditions are detected . -* `output_sub_cycles`: `bool`, default: `false` - If true, every sub-cycle will be output . - -### `FullSolveMultiApp` -The `FullSolveMultiApp` performs a complete simulation during each execution . This is often used for steady-state fixed-point iterations . - -**Parameters:** -* `ignore_solve_not_converge`: `bool`, default: `false` - If true, the main app continues even if a sub-app's solve does not converge . - -## Data Transfer: `MultiAppTransfer` Base Class -Transfers are used to move information between applications in the MultiApp hierarchy . The `MultiAppTransfer` is the base class for these operations. Data can be transferred to and from `AuxiliaryVariable` fields, `Postprocessor` values, and `UserObject`s . - -**Classes & Methods:** -* `MultiAppTransfer`: Base class for all MultiApp transfer objects . - -**Transfer Types:** -* `MultiAppGeneralFieldShapeEvaluationTransfer`: Interpolates a field (solution or auxiliary) from one domain to another, populating an `AuxiliaryVariable` field in the receiving app . This is a more general and efficient implementation of field interpolation . - * **Parameters:** `from_multi_app`, `to_multi_app`, `source_variable`, `variable` . -* `MultiAppGeneralFieldNearestLocationTransfer`: Moves field data by matching nodes/centroids . -* `MultiAppGeneralFieldUserObjectTransfer`: Evaluates a "spatial" `UserObject` in one app at the other app's nodes/centroids and deposits the information into an `AuxiliaryVariable` field . -* `MultiAppPostprocessorTransfer`: Moves `Postprocessor` data from one app to another . - -**MOOSE Input Syntax (Example `MultiAppPostprocessorTransfer`):** -` ` `ini -[Transfers] - [pressure_drop_transfer] - type = MultiAppPostprocessorTransfer - from_multi_app = subchannel - from_postprocessor = total_pressure_drop_SC - to_postprocessor = core_delta_p_tgt - reduction_type = average - execute_on = 'timestep_end' - [] -[] -` ` ` - -## Execution Timing: `execute_on` -The `execute_on` parameter, inherited from `SetupInterface`, dictates when an object, including `MultiApp`s and `Transfers`, is executed during the simulation . This parameter controls the coupling scheme (explicit vs. implicit). - -**Parameters:** -* `execute_on`: `enum` - Controls when the `MultiApp` or `Transfer` is executed. - * `TIMESTEP_BEGIN`: Executed prior to the solve for each time step . - * `TIMESTEP_END`: Executed after the solve for each time step . - * `NONLINEAR`: Executed prior to each Jacobian evaluation . - * `MULTIAPP_FIXED_POINT_BEGIN`: Executed at the beginning of each fixed-point solve loop . - * `MULTIAPP_FIXED_POINT_END`: Executed at the end of each fixed-point solve loop . - * Other flags exist for various execution points . - -**Coupling Scheme Control:** -* **Explicit (Loose) Coupling:** If `MultiApp`s and `Transfers` are executed only once per time step (e.g., `TIMESTEP_END`), data is exchanged once, and the simulation proceeds . -* **Implicit (Tight) Coupling / Picard Iteration:** By setting `fixed_point_max_its` in the parent app's `Executioner` block to a value greater than 1, MOOSE performs Picard iterations, where data is exchanged and physics re-solved until convergence within a time step . - -## Picard Iteration -MOOSE performs fixed-point (Picard) iteration between parent and child apps to achieve tight coupling . This involves iterating back - -Wiki pages you might want to explore: -- [MOOSE Framework Overview (idaholab/moose)](https://deepwiki.com/idaholab/moose#1) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-nucleation-grain-growth.md b/packages/akms/src/akms/_bundled/global_nodes/moose-nucleation-grain-growth.md deleted file mode 100644 index a51a98c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-nucleation-grain-growth.md +++ /dev/null @@ -1,374 +0,0 @@ ---- -id: moose-nucleation-grain-growth -title: MOOSE Phase Field Nucleation and Grain Growth -domain: phase-field -subdomain: algorithmic -tags: -- nucleation -- grain-growth -- coarsening -- discrete-nucleation -- langevin-noise -- grain-tracker -- zener-pinning -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-derivative-parsed-material - type: requires - weight: 0.6 - note: Uses DerivativeParsedMaterial for free energy definitions -- to: moose-allen-cahn-cahn-hilliard - type: requires - weight: 0.7 - note: Grain growth uses Allen-Cahn evolution -- to: moose-multi-phase-component - type: requires - weight: 0.6 - note: Grain growth uses multi-order-parameter framework -- to: cm-phase-field-fracture - type: implements - weight: 0.3 - note: Nucleation and grain evolution use phase field order parameter framework ---- - -# MOOSE Phase Field Nucleation and Grain Growth - -Framework knowledge node covering 2 aspect(s) of Phase Field Nucleation and Grain Growth. - -## Nucleation models in MOOSE phase field - -MOOSE handles phase field nucleation primarily through the `DiscreteNucleation` system, which artificially triggers and stabilizes nuclei formation by modifying the free energy density or directly changing an order parameter . This system involves several components, including `DiscreteNucleationInserter` for managing nucleation sites, `DiscreteNucleationMap` for creating a smooth density map of nuclei, and `DiscreteNucleation` material for applying free energy penalties . - -## Classes & Methods - -* `DiscreteNucleationInserter::validParams()`: Defines the valid input parameters for the `DiscreteNucleationInserter` class . -* `DiscreteNucleationInserter::initialize()`: Clears insertion and deletion counters and expires old nuclei from the local list . -* `DiscreteNucleationInserter::execute()`: Checks each quadrature point for potential nucleation based on a probability density and adds new nuclei . -* `DiscreteNucleationInserter::addNucleus()`: Adds a new nucleus to the local list with its time, center, and radius . -* `DiscreteNucleationMap::validParams()`: Defines the valid input parameters for the `DiscreteNucleationMap` class . -* `DiscreteNucleationMap::execute()`: Rebuilds the spatial map of nucleation sites if required, calculating the distance to the closest nucleus and applying a smooth interface function . -* `DiscreteNucleation::validParams()`: Defines the valid input parameters for the `DiscreteNucleation` material . -* `DiscreteNucleation::computeProperties()`: Calculates the free energy penalty based on the difference between coupled variables and their target concentrations, modified by the nucleus mask from `DiscreteNucleationMap` . -* `DiscreteNucleationData::getValue()`: Returns diagnostic data such as the number of active nuclei, update status, total nucleation rate, or insertion/deletion counts . -* `DiscreteNucleationTimeStep::getValue()`: Provides a time step limit to control the probability of multiple nucleation events within a single time step . - -## Nucleation Algorithm - -### 1. Discrete Nucleation System Overview -The `DiscreteNucleation` system in MOOSE allows for the incorporation of nucleation phenomena in phase field simulations . It addresses the lack of intrinsic nucleation due to thermal fluctuations in phase field methods by artificially triggering and stabilizing nuclei . - -### 2. Nucleation Site Insertion -Nucleation sites are inserted into the phase field using the `DiscreteNucleationInserter` user object . This object manages a global list of active nucleus positions, their insertion times, centers, and radii . During each `execute()` call, it iterates through quadrature points, calculates a nucleation rate based on a material property, and uses a random number to determine if a nucleus should be added . - -` ` `cpp -// From DiscreteNucleationInserter::execute() -for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp) -{ - const Real rate = _probability[qp] * _JxW[qp] * _coord[qp]; // Calculate nucleation rate - _nucleation_rate += rate; - - const Real random = getRandomReal(); - - if (!_time_dep_stats) // Time-independent statistics - { - if (random < rate) - addNucleus(qp); - } - else // Time-dependent statistics - { - if (random < rate * _fe_problem.dt() && random < (1.0 - std::exp(-rate * _fe_problem.dt()))) - addNucleus(qp); - } -} -` ` ` - - -The `addNucleus` method then creates a `NucleusLocation` object with the current time plus a `hold_time`, the quadrature point's coordinates as the center, and a local radius . - -### 3. Classical Nucleation Theory (CNT) Integration: Rate-Based Nucleation -The `DiscreteNucleationInserter` integrates classical nucleation theory by using a `probability` material property, which represents the probability density for inserting a discrete nucleus . This `probability` can be a rate density for time-dependent statistics or a probability density for time-independent statistics . The total nucleation rate is integrated over the domain . - -### 4. Nucleation Seed Representation: Order Parameter Forcing and Smooth Insertion -Nucleation seeds are represented in two main ways: - -* **Free energy penalty based nucleation**: This approach modifies the local free energy density to make the nucleated state a lower energy state, driving solute diffusion or changing a non-conserved order parameter . The `DiscreteNucleation` material implements a harmonic form of this penalty . It calculates a penalty based on the difference between coupled variables (`op_names`) and their `op_values` (target concentrations), scaled by a `penalty` factor and a nucleus mask from `DiscreteNucleationMap` . - - ` ` `cpp - // From DiscreteNucleation::computeProperties() - const std::vector & nucleus = _map.nuclei(_current_elem); // Nucleus mask - for (_qp = 0; _qp < _qrule->n_points(); ++_qp) - { - // ... - const Real penalty = _penalty * nucleus[_qp]; // Modify penalty with nucleus mask - Real dc = (*_args[ii])[_qp] - _op_values[i]; // Deviation from target concentration - // ... - if (_prop_F) - (*_prop_F)[_qp] += dc * dc * penalty; // Build free energy correction - // ... - } - ` ` ` - - -* **Direct order parameter modification**: For non-conserved order parameters, such as in polycrystalline models with `GrainTracker`, direct modification can be used . This involves applying a `DiscreteNucleationForce` and a `Reaction` kernel to a reserved order parameter . - -The `DiscreteNucleationMap` user object creates a smooth density map for nuclei locations . It calculates a `value` for each quadrature point based on its distance `r` to the closest nucleus and a specified `int_width` (interface width) . This allows for smooth insertion of nuclei. - -` ` `cpp -// From DiscreteNucleationMap::execute() -Real value = 0.0; -if (r <= local_radius - _int_width / 2.0) // Inside circle -{ - active_nuclei++; - value = 1.0; -} -else if (r < local_radius + _int_width / 2.0) // Smooth interface -{ - Real int_pos = (r - local_radius + _int_width / 2.0) / _int_width; - active_nuclei++; - value = (1.0 + std::cos(int_pos * libMesh::pi)) / 2.0; -} -` ` ` - - -### 5. Langevin Noise -The provided context mentions `LangevinNoise` as a separate mechanism for fluctuation-based nucleation . However, the `DiscreteNucleation` system itself introduces nucleation artificially and does not intrinsically rely on thermal fluctuations or `LangevinNoise` . - -### 6. Nucleation in Multi-Component Systems: Composition-Dependent Nucleation Barriers -The `DiscreteNucleation` material allows for coupling to multiple variables (`op_names`) and setting target values (`op_values`) for these variables . This enables the definition of composition-dependent nucleation barriers by specifying target concentrations for different components. The free energy penalty is then calculated based on the deviation from these target concentrations . - -### 7. Conservation Issues -The `DiscreteNucleation` system, particularly the free energy penalty approach, "eschews directly modifying conserved concentration and non-conserved order parameter fields" . Instead, it biases the thermodynamics to drive the formation of nuclei . For conserved order parameters, a `DerivativeSumMaterial` is used to add the nucleation free energy penalty to the physical free energy contributions, which are then utilized by a Cahn-Hilliard kernel . This suggests that mass conservation is handled by integrating the nucleation penalty into the existing conservation equations (e.g., Cahn-Hilliard). - -## Relationships - -` ` `mermaid -classDiagram - class DiscreteNucleationInserter { - +addNucleus() - -_probability - -_hold_time - -_local_nucleus_list - -_nucleation_rate - -_local_radius - -_time_dep_stats - } - - class DiscreteNucleationMap { - +nuclei() - -_inserter - -_nucleus_list - -_int_width - -_nucleus_map - } - - class DiscreteNucleation { - +computeProperties() - -_nvar - -_op_index - -_op_values - -_penalty - -_penalty_mode - -_map - } - - class DiscreteNucleationData { - +getValue() - -_inserter - -_nucleus_list - -_value_type - } - - class DiscreteNucleationTimeStep { - +getValue() - -_inserter - -_dt_nucleation - -_changes_made - -_rate - -_max_lambda - } - - DiscreteNucleationInserterBase <|-- DiscreteNucleationInserter - ElementUserObject <|-- DiscreteNucleationMap - DerivativeFunctionMaterialBase <|-- DiscreteNucleation - GeneralPostprocessor <|-- DiscreteNucleationData - GeneralPostprocessor <|-- DiscreteNucleationTimeStep - - DiscreteNucleationMap --> DiscreteNucleationInserter : uses _inserter - DiscreteNucleation --> DiscreteNucleationMap : uses _map - DiscreteNucleationData --> DiscreteNucleationInserterBase : uses _inserter - DiscreteNucleationTimeStep --> DiscreteNucleationInserterBase : uses _inserter -` ` ` - -## Parameters - -### `DiscreteNucleationInserter` -* `probability` (MaterialPropertyName, required): Probability density for inserting a discrete nucleus . -* `hold_time` (Real, required): Duration of time each nucleus is kept active after insertion . -* `radius` (MaterialPropertyName, default: "r_crit"): Variable radius material property name, or a constant value . -* `time - - -## Grain growth and coarsening - -MOOSE simulates grain growth and Ostwald ripening primarily through the phase-field method, utilizing a multi-order-parameter approach based on the Fan-Chen model. The `GrainTracker` object plays a crucial role in managing the order parameters, allowing the simulation to track more grains than the number of order parameters by remapping them as needed. Anisotropic grain boundary properties and various driving forces can be incorporated into the model. - -## Multi-order-parameter grain growth: the Fan-Chen or similar model - -MOOSE implements a multiphase grain growth model based on the work of Chen and Yang, and Moelans et al. . This model uses a system of Allen-Cahn equations to describe grain boundary migration . The evolution of each grain's order parameter ($\eta_i$) is governed by the equation: -$$ -\frac{\partial \eta_i}{\partial t} = - L \frac{\delta F}{\delta \eta_i} \quad (1) -$$ -where $F$ is the free energy functional and $L$ is the order parameter mobility . The free energy functional includes a local free energy density ($f_{loc}$), additional energy density sources ($f_{add}$), and a gradient term: -$$ -F = \int_V f_{loc}(\eta_0, \eta_1, \ldots, \eta_N) + f_{add} (\eta_0, \eta_1, \ldots, \eta_N) + \kappa \sum^N_i |\nabla \eta_i|^2 \quad (2) -$$ -For grain growth, the local free energy density is defined as: -$$ -f_{loc} = \mu \left( \sum_i^N \left(\frac{\eta_i^4}{4} - \frac{\eta_i^2}{2} \right) + \gamma \sum_{i=1}^N \sum_{j>i}^N \eta_i^2 \eta_j^2 + \frac{1}{4} \right) \quad (3) -$$ -Here, $N$ is the total number of order parameters, $\mu$ is the free energy weight, and $\gamma=1.5$ for symmetric interfacial profiles . - -The model parameters $L$, $\mu$, and $\kappa$ are related to the grain boundary energy ($\sigma$), diffuse grain boundary width ($w_{GB}$), and grain boundary mobility ($M_{GB}$) . - -The number of order parameters typically corresponds to the number of grains being simulated. However, the `GrainTracker` allows for simulating more grains than order parameters. - -## `GrainTracker` — how does it remap order parameters to track more grains than order parameters? - -The `GrainTracker` is a `Postprocessor` that enables the simulation of polycrystal grain growth with a number of grains exceeding the number of order parameters . It achieves this by remapping order parameters to different grains as needed to prevent unphysical grain coalescence when grains represented by the same variable come into contact . - -### Classes & Methods: -* `GrainTracker::GrainTracker(const InputParameters & parameters)`: Constructor for the `GrainTracker` class . -* `GrainTracker::validParams()`: Defines the input parameters for the `GrainTracker` object . -* `GrainTracker::initialize()`: Initializes the `GrainTracker` object . -* `GrainTracker::execute()`: Performs the grain tracking and remapping logic . -* `GrainTracker::finalize()`: Finalizes the `GrainTracker` object . -* `GrainTracker::assignGrains()`: Assigns a unique ID to each `FeatureData` object (grain) during the initial tracking phase . -* `GrainTracker::trackGrains()`: Compares incoming `FeatureData` objects with previous time step information to track grains over time . -* `GrainTracker::remapGrains()`: Remaps grains that are too close to each other to different order parameters . -* `GrainTracker::attemptGrainRenumber(FeatureData & grain, unsigned int depth, unsigned int max_depth)`: A recursive function that attempts to remap a grain to a new index . -* `GrainTracker::swapSolutionValues(FeatureData & grain, std::size_t new_var_index, std::vector> & cache, RemapCacheMode cache_mode)`: Moves solution values from a given grain to a new variable number during remapping . -* `FauxGrainTracker`: A lightweight replacement for `GrainTracker` when remapping is not needed, suitable when the number of grains is less than or equal to the number of order parameters . - -### Algorithm Steps: -The `GrainTracker`'s remapping algorithm is executed within the `remapGrains()` method . - -` ` `pseudocode -FUNCTION remapGrains() - grains_remapped = true - WHILE grains_remapped IS TRUE - grains_remapped = false - notify_ids.clear() - - FOR EACH grain1 IN _feature_sets - // Remap grains on reserved order parameters - IF grain1._var_index >= _reserve_op_index THEN - IF _verbosity_level > 0 THEN - PRINT "Grain #", grain1._id, " detected on a reserved order parameter #", grain1._var_index, ", remapping to another variable" - END IF - FOR max FROM 0 TO _max_remap_recursion_depth - IF attemptGrainRenumber(grain1, 0, max) THEN - BREAK - END IF - END FOR - IF NOT attemptGrainRenumber(grain1, 0, _max_remap_recursion_depth + 1) THEN - ERROR "Unable to find suitable order parameters for remapping for Grain #", grain1._id - END IF - grains_remapped = true - END IF - - FOR EACH grain2 IN _feature_sets - IF grain1 IS grain2 THEN CONTINUE - IF grain1._var_index == grain2._var_index AND // Grains represented by same variable - grain1._id != grain2._id AND // Different grains - grain1.boundingBoxesIntersect(grain2) AND // Bounding boxes intersect - grain1.halosIntersect(grain2) THEN // Halos actually overlap - IF _verbosity_level > 0 THEN - PRINT "Grain #", grain1._id, " intersects Grain #", grain2._id, " (variable index: ", grain1._var_index, ")" - END IF - FOR max FROM 0 TO _max_remap_recursion_depth - IF attemptGrainRenumber(grain1, 0, max) THEN - grains_remapped = true - BREAK - END IF - END FOR - IF NOT attemptGrainRenumber(grain1, 0, _max_remap_recursion_depth + 1) AND - NOT attemptGrainRenumber(grain2, 0, _max_remap_recursion_depth + 1) THEN - notify_ids.insert(grain1._id) - notify_ids.insert(grain2._id) - END IF - END IF - END FOR - END FOR - - IF notify_ids IS NOT EMPTY THEN - IF _tolerate_failure THEN - WARNING "Unable to find suitable order parameters for remapping for grain IDs: ", notify_ids - ELSE - ERROR "Unable to find suitable order parameters for remapping for grain IDs: ", notify_ids - END IF - END IF - END WHILE -END FUNCTION -` ` ` - -### Parameters: -* `remap = true/false`: Boolean parameter to enable or disable grain remapping . -* `_reserve_op_index`: The index above which order parameters are considered reserved and trigger remapping if a grain is found on them . -* `_max_remap_recursion_depth`: The maximum recursion depth for the `attemptGrainRenumber` method . -* `_tolerate_failure`: If `true`, the simulation will issue a warning instead of an error if remapping fails . - -### Relationships: -` ` `mermaid -classDiagram - class FeatureFloodCount { - +execute() - #_feature_sets - } - class GrainTracker { - +remapGrains() - #_feature_sets_old - #_remap - #_tolerate_failure - #_reserve_op_index - #_max_remap_recursion_depth - #attemptGrainRenumber() - #swapSolutionValues() - } - class GrainTrackerInterface { - <> - +getFeatureVar() - +getGrainCentroid() - } - class PolycrystalUserObjectBase { - #prepopulateState() - } - - GrainTracker --|> FeatureFloodCount : extends - GrainTracker --|> GrainTrackerInterface : implements - GrainTracker "1" -- "1" PolycrystalUserObjectBase : uses > _poly_ic_uo - FeatureFloodCount "1" *-- "many" FeatureData : contains - GrainTracker "1" *-- "many" FeatureData : _feature_sets_old -` ` ` - -## Grain boundary energy: how is anisotropic GB energy specified? - -While the basic grain growth model assumes isotropic grain boundary properties , MOOSE provides the `GBAnisotropy` material to define parameters $L$, $\mu$, and $\kappa$ considering misorientation dependence for the GB energy . This allows for specifying anisotropic grain boundary energy. - -## Grain boundary mobility: isotropic vs anisotropic, temperature-dependent - -### Isotropic Mobility -For isotropic grain boundary mobility, the model parameters $L$, $\mu$, and $\kappa$ are defined in terms of the grain boundary energy ($\sigma$), diffuse grain boundary width ($w_{GB}$), and grain boundary mobility ($M_{GB}$) . The `GBEvolution` material defines these parameters assuming isotropic properties . - -### Anisotropic Mobility -Anisotropic mobilities can be specified using the `anisotropic` parameter in actions like `GrandPotentialKernelAction` . The `GBAnisotropy` material also allows for misorientation-dependent grain boundary properties - -Wiki pages you might want to explore: -- [Physics Modules (idaholab/moose)](https://deepwiki.com/idaholab/moose#5) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-object-factory.md b/packages/akms/src/akms/_bundled/global_nodes/moose-object-factory.md deleted file mode 100644 index 328b017..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-object-factory.md +++ /dev/null @@ -1,390 +0,0 @@ ---- -id: moose-object-factory -title: MOOSE MOOSE Object System — Factory and Registration -domain: architecture -subdomain: procedural -tags: -- factory-pattern -- registration -- validParams -- input-parameters -- kernel -- material -- boundary-condition -- aux-kernel -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: tgs-dom-fem - type: implements - weight: 0.6 - note: MOOSE object system underpins FEM kernel/material registration -- to: tgs-ref-style-architecture - type: implements - weight: 0.5 - note: Factory pattern defines the framework's extension architecture ---- - -# MOOSE MOOSE Object System — Factory and Registration - -Framework knowledge node covering 2 aspect(s) of MOOSE Object System — Factory and Registration. - -## Object factory and registration pattern - -The MOOSE framework utilizes a robust object factory and registration system to dynamically create objects based on input file specifications. This system is centered around the `MooseObjectFactory` (referred to as `Factory` in the code) and the `Registry` . Classes declare their input parameters using a `static InputParameters validParams()` method , which the factory uses to validate and construct objects. - -## 1. How `registerMooseObject()` macro works - -The `registerMooseObject()` macro is used to register a C++ class with the MOOSE framework's `Registry` . This macro creates a static character variable whose initialization calls `Registry::add()` . - -It registers the class name (as a string) along with a factory function (implicitly, through the template `classname`) that can create an instance of that class . This allows the `Factory` to later construct objects of this type using only their string name from the input file . - -**Code Snippet:** -` ` `cpp -#define registerMooseObject(app, classname) \ - static char combineNames(dummyvar_for_registering_obj_##classname, __COUNTER__) = \ - Registry::add({app, #classname, "", "", __FILE__, __LINE__, "", ""}) -` ` ` - -**Example Usage:** -` ` `cpp -registerMooseObject("MooseApp", BlockWeightedPartitioner); -` ` ` -This line registers the `BlockWeightedPartitioner` class with the "MooseApp" application label . - -## 2. The `MooseObjectFactory` (referred to as `Factory`) - -The `Factory` class is responsible for creating MOOSE objects from input file type strings. When an object needs to be created, the `Factory::create()` method is called with the object's type name (string), instance name, and `InputParameters` . - -The `createTempl` method (a template function underlying `create`) first retrieves the `RegistryEntryBase` associated with the `obj_name` from its internal map `_name_to_object` . This `RegistryEntryBase` contains the necessary information, including a factory function, to construct the actual C++ object . The `build()` or `buildShared()` method of the `registry_entry` is then invoked, passing the validated `InputParameters` to the object's constructor . - -## 3. `validParams()` — how each class declares its input parameters - -Every `MooseObject` (and its derived classes) declares its input parameters by implementing a `static InputParameters validParams()` method . This method returns an `InputParameters` object that defines all the parameters the class can accept, including their types, default values, and documentation strings . - -This follows a template pattern where each class explicitly defines its own parameter interface . Derived classes typically start by calling the `validParams()` method of their parent class to inherit parameters, then add their own specific parameters . - -**Code Snippet:** -` ` `cpp -InputParameters -Convection::validParams() -{ - InputParameters params = Kernel::validParams(); // Start with parent - params.addRequiredParam("velocity", "Velocity Vector"); - params.addParam("coefficient", "Diffusion coefficient"); - return params; -} -` ` ` - -## 4. Parameter types: `MooseEnum`, `std::vector<>`, coupled variable references - -MOOSE supports various parameter types, including: -* **`MooseEnum`**: A "smart" enum utility that handles both integer and string contexts and is self-checked for consistency . It is declared by providing a space-separated list of valid options and an optional default value . - **Example:** - ` ` `cpp - MooseEnum order( - "CONSTANT FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH EIGHTH NINTH TENTH ELEVENTH TWELFTH " - "THIRTEENTH FOURTEENTH FIFTEENTH SIXTEENTH SEVENTEENTH EIGHTTEENTH NINETEENTH TWENTIETH " - "TWENTYFIRST TWENTYSECOND TWENTYTHIRD TWENTYFOURTH TWENTYFIFTH TWENTYSIXTH TWENTYSEVENTH " - "TWENTYEIGHTH TWENTYNINTH THIRTIETH THIRTYFIRST THIRTYSECOND THIRTYTHIRD THIRTYFOURTH " - "THIRTYFIFTH THIRTYSIXTH THIRTYSEVENTH THIRTYEIGHTH THIRTYNINTH FORTIETH FORTYFIRST " - "FORTYSECOND FORTYTHIRD", - "FIRST", - true); - params.addParam("order", - order, - "Order of the FE shape function to use for this variable (additional " - "orders not listed here are allowed, depending on the family)."); - ` ` ` - -* **`std::vector<>`**: Standard C++ vectors are supported for lists of values . - **Example:** - ` ` `cpp - params.addRequiredParam>( - "block", "The list of block ids (SubdomainID) that this object will be applied"); - ` ` ` - -* **Coupled Variable References**: These are declared using `addCoupledVar()` . This method takes the variable name and an optional documentation string . - **Example:** - ` ` `cpp - params.addCoupledVar("temperature", 0.0, "Coupled temperature"); - params.addCoupledVar("external_fields", - "The external fields that can be used in the UMAT subroutine"); - ` ` ` - -## 5. Required vs optional parameters, default values, documentation strings - -The `InputParameters` class provides methods to define the characteristics of each parameter: -* **Required Parameters**: Declared using `addRequiredParam("name", "documentation string")` . These parameters *must* be supplied in the input file . - **Example:** - ` ` `cpp - params.addRequiredParam("month", "Provide the month you were born."); - ` ` ` - -* **Optional Parameters with Default Values**: Declared using `addParam("name", default_value, "documentation string")` . If the parameter is not provided in the input file, the specified `default_value` is used . - **Example:** - ` ` `cpp - params.addParam("year", 1980, "Provide the year you were born."); - ` ` ` - -* **Documentation Strings**: A string provided as the last argument to `addParam` or `addRequiredParam` . This string is used for generating documentation for the parameter . - -## 6. How the factory enforces parameter validation before object construction - -The `Factory` ensures parameter validation happens before object construction through a two-step process: -1. **`getValidParams()`**: When an object is requested, the `Factory` first calls `getValidParams()` on the registered class type to obtain a pristine `InputParameters` object containing all declared parameters and their default values . -2. **`initialize()`**: The `Factory::initialize()` method then takes the `InputParameters` provided by the user (from the input file) and merges them with the valid parameters obtained from `getValidParams()` . During this process, it performs validation, checking for required parameters, type correctness, and range constraints . -3. **Construction**: Only after successful validation and initialization of the `InputParameters` object is the actual object constructed by calling its constructor with the validated `InputParameters` . The `MooseObject` constructor itself contains an assertion to ensure it was constructed via the factory with validated parameters . - -## 7. The `InputParameters` class — key methods - -The `InputParameters` class is central to MOOSE's parameter system. Key methods include: -* `addRequiredParam("name", "doc_string")`: Adds a parameter that *must* be specified by the user . -* `addParam("name", default_value, "doc_string")`: Adds an optional parameter with a default value . -* `addCoupledVar("name", "doc_string")`: Adds a parameter that represents a coupled variable, allowing objects to depend on other variables in the simulation . - -## Complete pattern from `validParams()` declaration through factory construction - -### Classes & Methods: -* `MooseObject::validParams()`: Static method in `MooseObject` and its derivatives to declare input parameters . -* `InputParameters::addRequiredParam()`: Adds a mandatory parameter . -* `InputParameters::addParam()`: Adds an optional parameter, potentially with a default value . - -Wiki pages you might want to explore: -- [Core Application Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#2) - - -## MOOSE class hierarchy and system taxonomy - -This response outlines the core systems in MOOSE as requested, detailing their base classes, essential virtual methods to override, and typical execution patterns. - -## 1. Kernel — Volume Integrals (Weak Form Terms) - -**Base Class:** The primary base class for Kernels is `Kernel` . For automatic differentiation (AD) enabled Kernels, the base class is `ADKernel` . Both inherit from `KernelBase` . - -**Classes & Methods:** -* `Kernel::computeQpResidual()`: Computes the Kernel's contribution to the residual at a quadrature point. This method *must* be overridden . -* `Kernel::computeQpJacobian()`: Computes the Kernel's contribution to the diagonal Jacobian entries at a quadrature point . -* `Kernel::computeQpOffDiagJacobian(unsigned int jvar)`: Computes the off-diagonal Jacobian entries for coupling with other variables . - -**Execution Pattern:** -Kernels are responsible for computing terms in the weak form of a PDE. The `computeQpResidual()` method is called for each quadrature point within an element to calculate the residual contribution . Optionally, `computeQpJacobian()` and `computeQpOffDiagJacobian()` can be overridden to provide Jacobian contributions, which aid in solver convergence . These methods have access to various member variables like `_u` (variable value), `_grad_u` (variable gradient), `_test` (test function), and `_grad_test` (test function gradient) at the current quadrature point . - -**Code Snippets:** -` ` `cpp -// From framework/include/kernels/Kernel.h -protected: - /** - * Compute this Kernel's contribution to the residual at the current quadrature point - */ - virtual Real computeQpResidual() = 0; - - /** - * Compute this Kernel's contribution to the Jacobian at the current quadrature point - */ - virtual Real computeQpJacobian() { return 0; } - - /** - * For coupling standard variables - */ - virtual Real computeQpOffDiagJacobian(unsigned int /*jvar*/) { return 0; } -` ` ` -` ` `cpp -// From test/src/kernels/DiffMKernel.C -Real -DiffMKernel::computeQpResidual() -{ - return _diff[_qp] * _grad_test[_i][_qp] * _grad_u[_qp] - _offset; -} - -Real -DiffMKernel::computeQpJacobian() -{ - return _diff[_qp] * _grad_test[_i][_qp] * _grad_phi[_j][_qp]; -} -` ` ` - -## 2. BoundaryCondition — DirichletBC, NeumannBC, IntegratedBC - -**Base Class:** The base class for boundary conditions is `BoundaryCondition` . Integrated boundary conditions derive from `IntegratedBCBase` , while Dirichlet boundary conditions typically derive from `DirichletBCBase` . - -**Classes & Methods:** -* `IntegratedBCBase::computeQpResidual()`: (Implicitly, through `BoundaryCondition` and its derivatives) Computes the residual contribution from the boundary condition at a quadrature point. -* `IntegratedBCBase::computeQpJacobian()`: (Implicitly) Computes the Jacobian contribution from the boundary condition at a quadrature point. - -**Execution Pattern:** -Boundary conditions contribute to the residual and Jacobian on the boundaries of the domain. For `IntegratedBCBase` objects, the `computeQpResidual()` and `computeQpJacobian()` methods are called for quadrature points on the boundary faces of elements . These methods have access to boundary-specific data such as `_current_side`, `_current_side_volume`, and `_current_boundary_id` . - -**Code Snippets:** -` ` `cpp -// From framework/include/bcs/IntegratedBCBase.h -class IntegratedBCBase : public BoundaryCondition, - public CoupleableMooseVariableDependencyIntermediateInterface, - public MaterialPropertyInterface -{ -public: - static InputParameters validParams(); - - IntegratedBCBase(const InputParameters & parameters); - - void prepareShapes(unsigned int var_num) override final; - - virtual bool shouldApply() const override; - -protected: - /// current element - const Elem * const & _current_elem; - /// Volume of the current element - const Real & _current_elem_volume; - /// current side of the current element - const unsigned int & _current_side; - /// current side element - const Elem * const & _current_side_elem; - /// Volume of the current side - const Real & _current_side_volume; - /// The currenty boundary id - const BoundaryID & _current_boundary_id; - - /// quadrature point index - unsigned int _qp; - /// active quadrature rule - const QBase * const & _qrule; - /// active quadrature points - const MooseArray & _q_point; - /// transformed Jacobian weights - const MooseArray & _JxW; - /// coordinate transformation - const MooseArray & _coord; - /// i-th, j-th index for enumerating test and shape functions - unsigned int _i, _j; -` ` ` - -## 3. Material — MaterialProperty Computation - -**Base Class:** The base class for materials is `MaterialBase` . - -**Classes & Methods:** -* `MaterialBase::computeProperties()`: This pure virtual method *must* be overridden to compute material properties . -* `MaterialBase::initStatefulProperties(const unsigned int n_points)`: Initializes stateful properties . - -**Execution Pattern:** -Material objects compute spatially and/or temporally varying properties, which are typically indexed at individual quadrature points . The `computeProperties()` method is invoked to calculate these properties, which can then be accessed by other MOOSE systems like Kernels and Boundary Conditions . Materials can also declare and consume properties from other materials or variables . - -**Code Snippets:** -` ` `cpp -// From framework/include/materials/MaterialBase.h -class MaterialBase : public MooseObject, - public BlockRestrictable, - public BoundaryRestrictable, - public SetupInterface, - public MooseVariableDependencyInterface, - public ScalarCoupleable, - public FunctionInterface, - public DistributionInterface, - public UserObjectInterface, - public TransientInterface, - public PostprocessorInterface, - public VectorPostprocessorInterface, - public DependencyResolverInterface, - public Restartable, - public MeshChangedInterface, - public OutputInterface, - public RandomInterface, - public ElementIDInterface, - protected GeometricSearchInterface, - protected ADFunctorInterface -{ -public: - static InputParameters validParams(); - - MaterialBase(const InputParameters & parameters); - -#ifdef MOOSE_KOKKOS_ENABLED - /** - * Special constructor used for Kokkos functor copy during parallel dispatch - */ - MaterialBase(const MaterialBase & object, const Moose::Kokkos::FunctorCopy & key); -#endif - - /** - * Initialize stateful properties (if material has some) - * - * This is _only_ called if this material has properties that are - * requested as stateful - */ - virtual void initStatefulProperties(const unsigned int n_points); - - virtual bool isInterfaceMaterial() { return false; }; - - /** - * Performs the quadrature point loop, calling computeQpProperties - */ - virtual void computeProperties() = 0; -` ` ` - -## 4. AuxKernel — Auxiliary Variable Computation - -**Base Class:** The base class for auxiliary kernels is `AuxKernelTempl` , which inherits from `AuxKernelBase` . `AuxKernel` is a typedef for `AuxKernelTempl` . - -**Classes & Methods:** -* `AuxKernelTempl::computeValue()`: This pure virtual method *must* be overridden to compute the value of the auxiliary variable . -* `AuxKernelTempl::compute()`: Computes the value and stores it in the solution vector . - -**Execution Pattern:** -AuxKernels compute and set explicitly known values of auxiliary variables . Unlike Kernels, AuxKernels do not compute residuals and do not involve test functions . The `computeValue()` method is called to determine the value of the auxiliary variable, which is then inserted into the auxiliary solution vector . AuxKernels can operate on elemental or nodal auxiliary variables . - -**Code Snippets:** -` ` `cpp -// From framework/include/auxkernels/AuxKernel.h -protected: - /** - * Compute and return the value of the aux variable. - */ - virtual ComputeValueType computeValue() = 0; -` ` ` -` ` `cpp -// From framework/include/auxkernels/AuxKernel.h - /** - * Computes the value and stores it in the solution vector - */ - virtual void compute() override; -` ` ` - -## 5. UserObject — General Computation Objects (Postprocessors, VectorPostprocessors) - -**Base Class:** The base class for UserObjects is `UserObject` . - -**Classes & Methods:** -* `UserObject::execute()`: Performs the main computation of the UserObject. -* `UserObject::getValue()`: Returns the computed value of the UserObject. - -**Execution Pattern:** -UserObjects are general computation objects that can perform various tasks. They are often used for post-processing, data analysis, or to provide values to other MOOSE objects . The `execute()` method is called at different times depending on the type of UserObject (e.g., `GeneralPostprocessor`, `NodalPostprocessor`, `ElementalPostprocessor`) and the configured execution flags . The `getValue()` method is responsible for returning the result of the computation . - -## 6. Constraint — Nodal/Mortar Constraints - -**Base Class:** The base class for constraints is `Constraint` . Specific types include `NodalConstraint` and `MortarConstraint` . - -**Classes & Methods:** -* `Constraint::constrain()`: Applies the constraint to the system. - -**Execution Pattern:** -Constraints are used to enforce relationships between degrees of freedom, such as nodal constraints or mortar constraints for non-conforming meshes. They modify the system's residual and Jacobian to impose these conditions. The `constrain()` method is typically called during the assembly process to apply the constraint equations. - -## 7. DGKernel — Discontinuous Galerkin - -**Base Class:** The base class for Discontinuous Galerkin (DG) Kernels is `DGKernelBase` . - -**Classes & Methods:** -* `DGKernelBase::computeQpResidual()`: Computes the residual contribution for DG terms at a quadrature point. -* `DGKernelBase::computeQpJacobian()`: Computes the Jacobian contribution for DG terms at a quadrature point. - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-objective-stress-rates.md b/packages/akms/src/akms/_bundled/global_nodes/moose-objective-stress-rates.md deleted file mode 100644 index 0a33f42..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-objective-stress-rates.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: moose-objective-stress-rates -title: MOOSE Objectivity and stress rate formulations -domain: constitutive -subdomain: algorithmic -tags: -- jaumann-rate -- truesdell-rate -- green-naghdi -- hughes-winget -- spin-tensor -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-objectivity-frame-operations - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-objectivity-frame-operations -- to: cm-objective-rates - type: implements - weight: 0.9 - note: Objective stress rate implementations ---- - -# MOOSE Objectivity and stress rate formulations - -MOOSE handles objectivity in large-deformation solid mechanics primarily through the `ComputeLagrangianObjectiveStress` class, which provides an interface to convert small-deformation constitutive models to large-deformation formulations by integrating objective stress rates . This class supports Truesdell, Jaumann, and Green-Naghdi objective rates, with Truesdell being the default . Additionally, the `ComputeFiniteStrain` class offers different decomposition methods, including Hughes-Winget, for calculating strain and rotation increments . - -## Objective Stress Rates -MOOSE provides three objective stress rates within the `ComputeLagrangianObjectiveStress` class: Truesdell, Jaumann, and Green-Naghdi . The default rate is Truesdell . - -### Truesdell Rate -The Truesdell rate is defined by the kinematic tensor $Q_{ik} = l_{ik}$ . The `objectiveUpdateTruesdell` method in `ComputeLagrangianObjectiveStress` implements this update . - -### Jaumann Rate -The Jaumann rate is defined by the kinematic tensor $Q_{ik} = w_{ik}$, where $w_{ik} = \frac{1}{2}(l_{ik} - l_{ki})$ is the spin tensor . This is explicitly implemented in the `objectiveUpdateJaumann` method . - -### Green-Naghdi Rate -The Green-Naghdi rate is defined by $Q_{ik} = \Omega_{ik} = \dot{R}_{ij} R_{kj}$ . This rate can be selected using `objective_rate = green_naghdi` and is implemented in `objectiveUpdateGreenNaghdi` . - -## Hughes-Winget Algorithm -The Hughes-Winget method is an option within the `ComputeFiniteStrain` class for calculating strain and rotation increments . When `_use_hw` is true, the deformation gradient midpoint `_def_grad_mid` and `_f_bar` are computed . The old mechanical and total strains are rotated using the `_rotation_increment` when the Hughes-Winget method is active . - -## `ComputeFiniteStrain::decomposition_method` Parameter -The `decomposition_method` parameter in `ComputeFiniteStrain` controls how strain and rotation increments are calculated . The available options are `TaylorExpansion`, `EigenSolution`, and `HughesWinget` . This parameter directly influences the objectivity treatment by determining the method for computing the incremental rotation and strain . - -## Rotation Tensor in Stress Update -For the Green-Naghdi rate, polar decomposition ($F = R \cdot U$) is performed to obtain the rotation tensor $R$ . The rotation tensor `_rotation` and its derivative `_d_rotation_d_def_grad` are declared if `_polar_decomp` is true . The Green-Naghdi rate uses $\Omega_{ik} = \dot{R}_{ij} R_{kj}$ as its kinematic tensor . - -## Hypoelastic Models and Strain Rate Objectification -For hypoelastic models, such as `ComputeHypoelasticStVenantKirchhoffStress`, the small stress update is given by $S_{n+1} = S_n + C : dD$ . The `ComputeLagrangianObjectiveStress` class handles the objectification of the stress rate by integrating an objective rate of the Cauchy stress . The `computeQpSmallStress` method in derived classes like `ComputeHypoelasticStVenantKirchhoffStress` calculates the small stress and Jacobian, which are then used by `ComputeLagrangianObjectiveStress` to perform the objective integration if `_large_kinematics` is true . - -## Classes & Methods -* `ComputeLagrangianObjectiveStress::validParams()`: Defines valid input parameters for the objective stress computation . -* `ComputeLagrangianObjectiveStress::computeQpCauchyStress()`: Orchestrates the computation of Cauchy stress, performing objective integration if large kinematics are enabled . -* `ComputeLagrangianObjectiveStress::computeQpSmallStress()`: A virtual method to be implemented by derived classes to provide the small stress update . -* `ComputeLagrangianObjectiveStress::objectiveUpdateTruesdell(const RankTwoTensor & dS)`: Implements the objective update using the Truesdell rate . -* `ComputeLagrangianObjectiveStress::objectiveUpdateJaumann(const RankTwoTensor & dS)`: Implements the objective update using the Jaumann rate . -* `ComputeLagrangianObjectiveStress::objectiveUpdateGreenNaghdi(const RankTwoTensor & dS)`: Implements the objective update using the Green-Naghdi rate . -* `ComputeFiniteStrain::validParams()`: Defines valid input parameters for finite strain computation, including `decomposition_method` . -* `ComputeFiniteStrain::computeProperties()`: Computes strain and rotation increments based on the chosen decomposition method . -* `ComputeFiniteStrain::computeQpIncrements(RankTwoTensor & total_strain_increment, RankTwoTensor & rotation_increment)`: Calculates the strain and rotation increments using the specified decomposition method . -* `ComputeHypoelasticStVenantKirchhoffStress::computeQpSmallStress()`: Implements the elastic small stress update for the St. Venant-Kirchhoff model . - -## Equations -### General Objective Rate Form -The general form for objective rates is given by: -$$ -\hat{\sigma}_{ij} = s_{ij}=\dot{\sigma}_{ij}-Q_{ik}\sigma_{kj}-\sigma_{ik}Q_{jk}+Q_{kk}\sigma_{ij} \quad (1) -$$ -where $Q_{ik}$ is a kinematic measure and $s_{ij}$ is the small stress. - -### Truesdell Rate Kinematic Tensor -The kinematic tensor for the Truesdell rate is: -$$ -Q_{ik}=l_{ik} \quad (2) -$$ - -### Jaumann Rate Kinematic Tensor -The kinematic tensor for the Jaumann rate is: -$$ -Q_{ik}=w_{ik} \quad (3) -$$ -with -$$ -w_{ik}=\frac{1}{2}\left(l_{ik}-l_{ki}\right) \quad (4) -$$ - -### Green-Naghdi Rate Kinematic Tensor -The kinematic tensor for the Green-Naghdi rate is: -$$ -Q_{ik} = \Omega_{ik} = \dot{R}_{ij} R_{kj} \quad (5) -$$ - -## Parameters -* `objective_rate = value`: Type: `MooseEnum`, Default: `truesdell`. Specifies the objective integration rate to use. Options are `truesdell`, `jaumann`, `green_naghdi` . -* `decomposition_method = value`: Type: `MooseEnum`, Default: `TaylorExpansion`. Specifies the method to calculate strain and rotation increments. Options are `TaylorExpansion`, `EigenSolution`, `HughesWinget` . - -## Relationships -` ` `mermaid -classDiagram - class ComputeLagrangianStressCauchy { - +computeQpCauchyStress() - } - class ComputeLagrangianObjectiveStress { - <> - +objectiveUpdateTruesdell() - +objectiveUpdateJaumann() - +objectiveUpdateGreenNaghdi() - +computeQpSmallStress() - -_rate - -_polar_decomp - -_rotation - -_rotation_old - -_d_rotation_d_def_grad - -_stretch - } - class ComputeHypoelasticStVenantKirchhoffStress { - +computeQpSmallStress() - } - class ComputeLagrangianWrappedStress { - +computeQpSmallStress() - } - class ComputeIncrementalStrainBase { - +computeProperties() - } - class ComputeFiniteStrain { - +computeProperties() - +computeQpIncrements() - -_decomposition_method - -_use_hw - -_def_grad_mid - -_f_bar - } - - ComputeLagrangianStressCauchy <|-- ComputeLagrangianObjectiveStress : inherits - ComputeLagrangianObjectiveStress <|-- ComputeHypoelasticStVenantKirchhoffStress : inherits - ComputeLagrangianObjectiveStress <|-- ComputeLagrangianWrappedStress : inherits - ComputeIncrementalStrainBase <|-- ComputeFiniteStrain : inherits - - ComputeLagrangianObjectiveStress ..> ComputeFiniteStrain : uses _rotation_increment (indirectly via _vorticity_increment) - ComputeLagrangianObjectiveStress ..> ComputeLagrangianObjectiveStress.ObjectiveRate : uses -` ` ` - -## Code Snippets -### `ComputeLagrangianObjectiveStress` Constructor and Member Variables -` ` `cpp -ComputeLagrangianObjectiveStress::ComputeLagrangianObjectiveStress( - const InputParameters & parameters) - : ComputeLagrangianStressCauchy(parameters), - _small_stress(declareProperty(_base_name + "small_stress")), - _small_stress_old(getMaterialPropertyOld(_base_name + "small_stress")), - _small_jacobian(declareProperty(_base_name + "small_jacobian")), - _cauchy_stress_old(getMaterialPropertyOld(_base_name + "cauchy_stress")), - _mechanical_strain(getMaterialPropertyByName(_base_name + "mechanical_strain")), - _strain_increment(getMaterialPropertyByName(_base_name + "strain_increment")), - _vorticity_increment( - getMaterialPropertyByName(_base_name + "vorticity_increment")), - _def_grad(getMaterialPropertyByName(_base_name + "deformation_gradient")), - _def_grad_old(getMaterialPropertyOldByName(_base_name + "deformation_gradient")), - _rate(getParam("objective_rate").getEnum()), - _polar_decomp(_rate == ObjectiveRate::GreenN - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-objectivity-frame-operations.md b/packages/akms/src/akms/_bundled/global_nodes/moose-objectivity-frame-operations.md deleted file mode 100644 index 8397879..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-objectivity-frame-operations.md +++ /dev/null @@ -1,552 +0,0 @@ ---- -id: moose-objectivity-frame-operations -title: MOOSE Objectivity — Push-Forward, Pull-Back, and Frame Operations -domain: constitutive -subdomain: algorithmic -tags: -- objectivity -- total-lagrangian -- push-forward -- pull-back -- hughes-winget -- jaumann-rate -- truesdell-rate -- stress-measures -- 2nd-piola-kirchhoff -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: large -reading_priority: full -akms_schema: v2 -edges: -- to: moose-stress-computation-chain - type: requires - weight: 0.7 - note: Part of the stress computation dispatch chain -- to: moose-strain-formulations - type: requires - weight: 0.8 - note: Frame operations depend on strain/deformation gradient -- to: cm-kinematics-tl - type: implements - weight: 0.9 - note: Implements total Lagrangian formulation and tensor transformations -- to: cm-objective-rates - type: implements - weight: 0.9 - note: Implements objective stress rate formulations (Jaumann, Truesdell) ---- - -# MOOSE Objectivity — Push-Forward, Pull-Back, and Frame Operations - -Framework knowledge node covering 4 aspect(s) of Objectivity — Push-Forward, Pull-Back, and Frame Operations. - -## Total Lagrangian formulation in MOOSE - -MOOSE implements a total Lagrangian formulation in Tensor Mechanics through specific kernels and material properties, primarily using the `TotalLagrangianStressDivergence` kernel and related `ComputeLagrangianStrain` and `ComputeLagrangianStressBase` material classes . This approach uses the initial, undeformed configuration as the reference for stress divergence calculations . - -## MOOSE's Total Lagrangian Implementation - -### 1. Total Lagrangian Approach and Stress Divergence -MOOSE implements the total Lagrangian approach by formulating the equilibrium equations in the initial, undeformed configuration . The stress divergence is computed using the 1st Piola-Kirchhoff stress tensor (`_pk1`) and the gradient of the test function in the reference configuration . - -The weak form of the stress divergence in the reference configuration is given by: -$$ -\int_{V_0} \mathbf{P} : \nabla_0 \delta \mathbf{u} \, dV_0 = \int_{V_0} \mathbf{b}_0 \cdot \delta \mathbf{u} \, dV_0 + \int_{A_0} \mathbf{t}_0 \cdot \delta \mathbf{u} \, dA_0 -$$ -where $\mathbf{P}$ is the 1st Piola-Kirchhoff stress tensor, $\nabla_0$ is the gradient with respect to the reference configuration, $\delta \mathbf{u}$ is the virtual displacement, $\mathbf{b}_0$ is the body force per unit reference volume, and $\mathbf{t}_0$ is the traction per unit reference area . - -The `TotalLagrangianStressDivergenceBase::computeQpResidual()` method calculates the residual contribution for the weak form as: -$$ -\text{gradTest}(\alpha) : \text{_pk1}[\text{_qp}] -$$ -where `gradTest` is the gradient of the test function and `_pk1` is the 1st Piola-Kirchhoff stress . - -### 2. `StressDivergenceTensors` with `use_displaced_mesh = false` -The `StressDivergenceTensors` kernel is part of the older kernel system . While it has a `use_displaced_mesh` parameter, setting it to `false` does not make it a total Lagrangian formulation in the context of the *new* Lagrangian kernel system . The new Lagrangian kernel system explicitly uses `TotalLagrangianStressDivergence` for the total Lagrangian path . The `TotalLagrangianStressDivergenceBase` explicitly suppresses the `use_displaced_mesh` parameter, enforcing that it is off . - -### 3. Deformation Gradient Computation and Storage -The deformation gradient `F` is computed by the `ComputeLagrangianStrain` class . For large deformations, it is calculated as $F_{iJ} = \delta_{iJ} + \frac{\partial u_i}{\partial X_J}$ . This `F` is then stored as a `MaterialProperty` and is accessible to other material models and kernels through its name, typically `deformation_gradient` . For example, `ComputeLagrangianStressCauchy` and `ComputeLagrangianStressPK1` retrieve it using `getMaterialPropertyByName(_base_name + "deformation_gradient")` . - -### 4. 2nd Piola-Kirchhoff Stress (S) vs Cauchy Stress (σ) -MOOSE's new Lagrangian material system, represented by `ComputeLagrangianStressBase`, is designed to provide both Cauchy stress (`_cauchy_stress`) and 1st Piola-Kirchhoff stress (`_pk1_stress`) . The 2nd Piola-Kirchhoff stress (`_S`) is typically computed by specialized material models like `ComputeLagrangianStressPK2` or `ComputeNeoHookeanStress` . - -The conversion from 2nd Piola-Kirchhoff stress (S) to 1st Piola-Kirchhoff stress (P) and then to Cauchy stress (σ) is handled within the `ComputeLagrangianStressPK2`, `ComputeLagrangianStressPK1`, and `ComputeLagrangianStressCauchy` classes . - -The conversion from 2nd Piola-Kirchhoff stress (S) to 1st Piola-Kirchhoff stress (P) is: -$$ -\mathbf{P} = \mathbf{F} \cdot \mathbf{S} \quad (1) -$$ -This is implemented in `ComputeLagrangianStressPK2::computeQpPK1Stress()` . - -The conversion from 1st Piola-Kirchhoff stress (P) to Cauchy stress (σ) is: -$$ -\sigma = \frac{1}{J} \mathbf{P} \cdot \mathbf{F}^T \quad (2) -$$ -This is implemented in `ComputeLagrangianStressPK1::computeQpCauchyStress()` . -Conversely, the conversion from Cauchy stress (σ) to 1st Piola-Kirchhoff stress (P) is: -$$ -\mathbf{P} = J \sigma \cdot \mathbf{F}^{-T} \quad (3) -$$ -This is implemented in `ComputeLagrangianStressCauchy::computeQpPK1Stress()` . - -### 5. Updated Lagrangian Option -MOOSE supports an updated Lagrangian formulation with `use_displaced_mesh = true` for large deformation kinematics . This is handled by the `UpdatedLagrangianStressDivergence` kernel . In this formulation, the equilibrium equations are written with respect to the current (deformed) configuration . The kernel requires the Cauchy stress (`_stress`) and its derivative with respect to the spatial velocity gradient (`_material_jacobian`) . - -### 6. Total Lagrangian vs. Updated Lagrangian Trade-offs -The choice between total Lagrangian and updated Lagrangian formulations in MOOSE is primarily managed by the `formulation` parameter within the `Physics/SolidMechanics/QuasiStatic` action, which can be set to `TOTAL` or `UPDATED` . - -* **Total Lagrangian:** - * Uses the initial configuration as the reference . - * Requires the 1st Piola-Kirchhoff stress and its derivative with respect to the deformation gradient . - * The `TotalLagrangianStressDivergence` kernel explicitly sets `use_displaced_mesh = false` . - * Homogenization constraints currently only support the total Lagrangian formulation . - -* **Updated Lagrangian:** - * Uses the current (deformed) configuration as the reference . - * Requires the Cauchy stress and its derivative with respect to the spatial velocity gradient . - * The `UpdatedLagrangianStressDivergence` kernel requires `use_displaced_mesh = true` for large kinematics . - -The trade-offs involve whether the reference configuration needs to be recomputed at each step (updated Lagrangian) or remains constant (total Lagrangian). The total Lagrangian formulation simplifies some aspects by always referring to the initial geometry, while the updated Lagrangian formulation is often more natural for rate-dependent material models. - -### 7. `ComputeLagrangianStrain` vs. `ComputeFiniteStrain` -* **`ComputeLagrangianStrain`**: This class is part of the new Lagrangian kernel system . It calculates kinematic quantities for both small and large deformation theories, controlled by the `large_kinematics` flag . It computes the deformation gradient `F` and various strain measures, including incremental and total strains . It also includes stabilization options like $\bar{F}$ stabilization . It explicitly requires `use_displaced_mesh=false` . - -* **`ComputeFiniteStrain`**: This class belongs to the older kernel system . It calculates finite strain measures but is not directly integrated with the new Lagrangian kernel system's material and kernel interfaces . The new Lagrangian kernel system aims to provide exact large deformation Jacobians without requiring AD, which is a key difference . - -The formulation choice propagates through the code via the `_lagrangian_kernels` and `_lk_formulation` flags within the `QuasiStaticSolidMechanicsPhysics` action . These flags determine which stress divergence kernel (`TotalLagrangianStressDivergence` or `UpdatedLagrangianStressDivergence`) and which strain calculator (`ComputeLagrangianStrain`) are instantiated . - -## Classes & Methods - -* `TotalLagrangianStressDivergenceBase::computeQpResidual()`: Calculates the residual contribution for the total Lagrangian weak form - - -## Objectivity and stress rate formulations - -MOOSE handles objectivity in large-deformation solid mechanics primarily through the `ComputeLagrangianObjectiveStress` class, which provides an interface to convert small-deformation constitutive models to large-deformation formulations by integrating objective stress rates . This class supports Truesdell, Jaumann, and Green-Naghdi objective rates, with Truesdell being the default . Additionally, the `ComputeFiniteStrain` class offers different decomposition methods, including Hughes-Winget, for calculating strain and rotation increments . - -## Objective Stress Rates -MOOSE provides three objective stress rates within the `ComputeLagrangianObjectiveStress` class: Truesdell, Jaumann, and Green-Naghdi . The default rate is Truesdell . - -### Truesdell Rate -The Truesdell rate is defined by the kinematic tensor $Q_{ik} = l_{ik}$ . The `objectiveUpdateTruesdell` method in `ComputeLagrangianObjectiveStress` implements this update . - -### Jaumann Rate -The Jaumann rate is defined by the kinematic tensor $Q_{ik} = w_{ik}$, where $w_{ik} = \frac{1}{2}(l_{ik} - l_{ki})$ is the spin tensor . This is explicitly implemented in the `objectiveUpdateJaumann` method . - -### Green-Naghdi Rate -The Green-Naghdi rate is defined by $Q_{ik} = \Omega_{ik} = \dot{R}_{ij} R_{kj}$ . This rate can be selected using `objective_rate = green_naghdi` and is implemented in `objectiveUpdateGreenNaghdi` . - -## Hughes-Winget Algorithm -The Hughes-Winget method is an option within the `ComputeFiniteStrain` class for calculating strain and rotation increments . When `_use_hw` is true, the deformation gradient midpoint `_def_grad_mid` and `_f_bar` are computed . The old mechanical and total strains are rotated using the `_rotation_increment` when the Hughes-Winget method is active . - -## `ComputeFiniteStrain::decomposition_method` Parameter -The `decomposition_method` parameter in `ComputeFiniteStrain` controls how strain and rotation increments are calculated . The available options are `TaylorExpansion`, `EigenSolution`, and `HughesWinget` . This parameter directly influences the objectivity treatment by determining the method for computing the incremental rotation and strain . - -## Rotation Tensor in Stress Update -For the Green-Naghdi rate, polar decomposition ($F = R \cdot U$) is performed to obtain the rotation tensor $R$ . The rotation tensor `_rotation` and its derivative `_d_rotation_d_def_grad` are declared if `_polar_decomp` is true . The Green-Naghdi rate uses $\Omega_{ik} = \dot{R}_{ij} R_{kj}$ as its kinematic tensor . - -## Hypoelastic Models and Strain Rate Objectification -For hypoelastic models, such as `ComputeHypoelasticStVenantKirchhoffStress`, the small stress update is given by $S_{n+1} = S_n + C : dD$ . The `ComputeLagrangianObjectiveStress` class handles the objectification of the stress rate by integrating an objective rate of the Cauchy stress . The `computeQpSmallStress` method in derived classes like `ComputeHypoelasticStVenantKirchhoffStress` calculates the small stress and Jacobian, which are then used by `ComputeLagrangianObjectiveStress` to perform the objective integration if `_large_kinematics` is true . - -## Classes & Methods -* `ComputeLagrangianObjectiveStress::validParams()`: Defines valid input parameters for the objective stress computation . -* `ComputeLagrangianObjectiveStress::computeQpCauchyStress()`: Orchestrates the computation of Cauchy stress, performing objective integration if large kinematics are enabled . -* `ComputeLagrangianObjectiveStress::computeQpSmallStress()`: A virtual method to be implemented by derived classes to provide the small stress update . -* `ComputeLagrangianObjectiveStress::objectiveUpdateTruesdell(const RankTwoTensor & dS)`: Implements the objective update using the Truesdell rate . -* `ComputeLagrangianObjectiveStress::objectiveUpdateJaumann(const RankTwoTensor & dS)`: Implements the objective update using the Jaumann rate . -* `ComputeLagrangianObjectiveStress::objectiveUpdateGreenNaghdi(const RankTwoTensor & dS)`: Implements the objective update using the Green-Naghdi rate . -* `ComputeFiniteStrain::validParams()`: Defines valid input parameters for finite strain computation, including `decomposition_method` . -* `ComputeFiniteStrain::computeProperties()`: Computes strain and rotation increments based on the chosen decomposition method . -* `ComputeFiniteStrain::computeQpIncrements(RankTwoTensor & total_strain_increment, RankTwoTensor & rotation_increment)`: Calculates the strain and rotation increments using the specified decomposition method . -* `ComputeHypoelasticStVenantKirchhoffStress::computeQpSmallStress()`: Implements the elastic small stress update for the St. Venant-Kirchhoff model . - -## Equations -### General Objective Rate Form -The general form for objective rates is given by: -$$ -\hat{\sigma}_{ij} = s_{ij}=\dot{\sigma}_{ij}-Q_{ik}\sigma_{kj}-\sigma_{ik}Q_{jk}+Q_{kk}\sigma_{ij} \quad (1) -$$ -where $Q_{ik}$ is a kinematic measure and $s_{ij}$ is the small stress. - -### Truesdell Rate Kinematic Tensor -The kinematic tensor for the Truesdell rate is: -$$ -Q_{ik}=l_{ik} \quad (2) -$$ - -### Jaumann Rate Kinematic Tensor -The kinematic tensor for the Jaumann rate is: -$$ -Q_{ik}=w_{ik} \quad (3) -$$ -with -$$ -w_{ik}=\frac{1}{2}\left(l_{ik}-l_{ki}\right) \quad (4) -$$ - -### Green-Naghdi Rate Kinematic Tensor -The kinematic tensor for the Green-Naghdi rate is: -$$ -Q_{ik} = \Omega_{ik} = \dot{R}_{ij} R_{kj} \quad (5) -$$ - -## Parameters -* `objective_rate = value`: Type: `MooseEnum`, Default: `truesdell`. Specifies the objective integration rate to use. Options are `truesdell`, `jaumann`, `green_naghdi` . -* `decomposition_method = value`: Type: `MooseEnum`, Default: `TaylorExpansion`. Specifies the method to calculate strain and rotation increments. Options are `TaylorExpansion`, `EigenSolution`, `HughesWinget` . - -## Relationships -` ` `mermaid -classDiagram - class ComputeLagrangianStressCauchy { - +computeQpCauchyStress() - } - class ComputeLagrangianObjectiveStress { - <> - +objectiveUpdateTruesdell() - +objectiveUpdateJaumann() - +objectiveUpdateGreenNaghdi() - +computeQpSmallStress() - -_rate - -_polar_decomp - -_rotation - -_rotation_old - -_d_rotation_d_def_grad - -_stretch - } - class ComputeHypoelasticStVenantKirchhoffStress { - +computeQpSmallStress() - } - class ComputeLagrangianWrappedStress { - +computeQpSmallStress() - } - class ComputeIncrementalStrainBase { - +computeProperties() - } - class ComputeFiniteStrain { - +computeProperties() - +computeQpIncrements() - -_decomposition_method - -_use_hw - -_def_grad_mid - -_f_bar - } - - ComputeLagrangianStressCauchy <|-- ComputeLagrangianObjectiveStress : inherits - ComputeLagrangianObjectiveStress <|-- ComputeHypoelasticStVenantKirchhoffStress : inherits - ComputeLagrangianObjectiveStress <|-- ComputeLagrangianWrappedStress : inherits - ComputeIncrementalStrainBase <|-- ComputeFiniteStrain : inherits - - ComputeLagrangianObjectiveStress ..> ComputeFiniteStrain : uses _rotation_increment (indirectly via _vorticity_increment) - ComputeLagrangianObjectiveStress ..> ComputeLagrangianObjectiveStress.ObjectiveRate : uses -` ` ` - -## Code Snippets -### `ComputeLagrangianObjectiveStress` Constructor and Member Variables -` ` `cpp -ComputeLagrangianObjectiveStress::ComputeLagrangianObjectiveStress( - const InputParameters & parameters) - : ComputeLagrangianStressCauchy(parameters), - _small_stress(declareProperty(_base_name + "small_stress")), - _small_stress_old(getMaterialPropertyOld(_base_name + "small_stress")), - _small_jacobian(declareProperty(_base_name + "small_jacobian")), - _cauchy_stress_old(getMaterialPropertyOld(_base_name + "cauchy_stress")), - _mechanical_strain(getMaterialPropertyByName(_base_name + "mechanical_strain")), - _strain_increment(getMaterialPropertyByName(_base_name + "strain_increment")), - _vorticity_increment( - getMaterialPropertyByName(_base_name + "vorticity_increment")), - _def_grad(getMaterialPropertyByName(_base_name + "deformation_gradient")), - _def_grad_old(getMaterialPropertyOldByName(_base_name + "deformation_gradient")), - _rate(getParam("objective_rate").getEnum()), - _polar_decomp(_rate == ObjectiveRate::GreenN - - -## Push-forward and pull-back tensor operations - -MOOSE implements push-forward and pull-back operations for tensor quantities, particularly stress and elasticity tensors, within its solid mechanics module for finite deformation analysis. These operations are primarily handled by specialized material classes that manage the transformation between different stress measures (Cauchy, 1st PK, 2nd PK) and their corresponding Jacobians. The `RankTwoTensor` and `RankFourTensor` classes provide fundamental tensor operations, but explicit `pushForward()` or `pullBack()` methods are not directly exposed at that level for general use; instead, these transformations are embedded within the material constitutive models. - -## Classes & Methods - -* `ComputeLagrangianStressCauchy::computeQpPK1Stress()`: Computes the 1st Piola-Kirchhoff stress from Cauchy stress and its Jacobian. -* `ComputeLagrangianStressPK1::computeQpCauchyStress()`: Computes the Cauchy stress from 1st Piola-Kirchhoff stress and its Jacobian. -* `ComputeLagrangianStressPK2::computeQpPK1Stress()`: Computes the 1st Piola-Kirchhoff stress from 2nd Piola-Kirchhoff stress and its Jacobian. -* `ComputeDeformGradBasedStress::computeQpStress()`: Computes Cauchy stress from 2nd PK stress using the deformation gradient. -* `ComputeHypoelasticStVenantKirchhoffStress::computeQpSmallStress()`: Performs push-forward of the elasticity tensor for large kinematics. -* `ComputeLagrangianObjectiveStress::objectiveUpdateTruesdell()`: Implements the Truesdell objective update for Cauchy stress and its Jacobian. -* `ComputeLagrangianObjectiveStress::polarDecomposition()`: Computes polar decomposition of the deformation gradient to get rotation and stretch tensors, and their derivatives. -* `CZMComputeGlobalTractionTotalLagrangian::computeEquilibriumTracionAndDerivatives()`: Computes the 1st Piola-Kirchhoff traction and its derivatives, including the area ratio. - -## Equations - -### 1. Pull-back of Cauchy stress to 2nd PK -The pull-back of Cauchy stress ($\sigma$) to 2nd Piola-Kirchhoff stress ($S$) is implicitly handled by the inverse transformation of the push-forward operation. While not directly expressed as $S = J \cdot F^{-1} \cdot \sigma \cdot F^{-T}$, the MOOSE framework typically computes stresses in a specific configuration and then transforms them as needed. For instance, `ComputeLagrangianStressPK2` is designed to provide the 2nd PK stress and its tangent, and then wraps this to provide the 1st PK stress. - -### 2. Push-forward of 2nd PK to Cauchy -The push-forward of 2nd Piola-Kirchhoff stress ($S$) to Cauchy stress ($\sigma$) is computed in `ComputeDeformGradBasedStress::computeQpStress()` and `ComputeLagrangianStressPK1::computeQpCauchyStress()` . - -$$ -\sigma = \frac{1}{J} \cdot F \cdot S \cdot F^T \quad (1) -$$ - -### 4. Elasticity tensor transformation -The 4th-order push-forward of the elasticity tensor from the reference to the current configuration is implemented in `ComputeHypoelasticStVenantKirchhoffStress::computeQpSmallStress()` . - -$$ -C_{spatial} = \frac{1}{J} \cdot F_{i\alpha} F_{j\beta} F_{k\gamma} F_{l\delta} \cdot C_{ref_{\alpha\beta\gamma\delta}} \quad (2) -$$ -This is represented in code as: -` ` `cpp - const RankTwoTensor F = _def_grad[_qp]; - const Real J = F.det(); - const RankFourTensor FF = F.times(F); - const RankFourTensor FtFt = F.times(F); - const RankFourTensor C0 = _elasticity_tensor[_qp]; - const RankFourTensor C = FF * C0 * FtFt / J; -` ` ` - -### 6. Piola transform for traction (Nanson's formula) -Nanson's formula is explicitly used in `CZMComputeGlobalTractionTotalLagrangian::computeEquilibriumTracionAndDerivatives()` to compute the area ratio for the 1st Piola-Kirchhoff traction. -The area ratio is calculated as: -$$ -\frac{da}{dA} = J \cdot ||F^T N|| \quad (3) -$$ -This is implemented using `CohesiveZoneModelTools::computeAreaRatio` . The 1st Piola-Kirchhoff traction is then computed as $T = \frac{da}{dA} Q \hat{t}$ , where $Q$ is the total rotation and $\hat{t}$ is the interface traction. - -## Algorithm Steps - -### Push-forward of 2nd PK to Cauchy Stress -` ` `pseudocode -function computeQpStress() - iden = RankTwoTensor::Identity() - ee = 0.5 * (_deformation_gradient.transpose() * _deformation_gradient - iden) - pk2 = _elasticity_tensor * ee - _stress = _deformation_gradient * pk2 * _deformation_gradient.transpose() / _deformation_gradient.det() - _Jacobian_mult = _elasticity_tensor -end function -` ` ` - -## Relationships - -` ` `mermaid -classDiagram - class Material { - +initQpStatefulProperties() - +computeQpProperties() - } - class ComputeLagrangianStressBase { - +computeQpStressUpdate() - #_large_kinematics - #_cauchy_stress - #_cauchy_jacobian - #_pk1_stress - #_pk1_jacobian - } - class ComputeLagrangianStressCauchy { - +computeQpCauchyStress() - -computeQpPK1Stress() - #_inv_df - #_inv_def_grad - #_F - } - class ComputeLagrangianStressPK1 { - +computeQpPK1Stress() - -computeQpCauchyStress() - #_inv_df - #_F - } - class ComputeLagrangianStressPK2 { - +computeQpPK2Stress() - #_E - #_S - #_C - } - class ComputeLagrangianObjectiveStress { - +computeQpSmallStress() - -objectiveUpdateTruesdell() - -objectiveUpdateJaumann() - -objectiveUpdateGreenNaghdi() - -advectStress() - -updateTensor() - -stressAdvectionDerivative() - -cauchyJacobian() - -polarDecomposition() - #_small_stress - #_small_jacobian - #_def_grad - #_rotation - #_stretch - } - class ComputeHypoelasticStVenantKirchhoffStress { - +computeQpSmallStress() - #_elasticity_tensor - #_def_grad - } - class ComputeDeformGradBasedStress { - +computeQpStress() - #_deformation_gradient - #_elasticity_tensor - #_stress - #_Jacobian_mult - } - class CZMComputeGlobalTractionTotalLagrangian { - +computeEquilibriumTracionAndDerivatives() - #_F - #_J - #_F_inv - #_area_ratio - #_PK1traction - #_dPK1traction_dF - } - - Material <|-- ComputeLagrangianStressBase - ComputeLagrangianStressBase <|-- ComputeLagrangianStressCauchy - ComputeLagrangianStressBase <|-- ComputeLagrangianStressPK1 - ComputeLagrangianStressPK1 <|-- ComputeLagrangianStressPK2 - ComputeLagrangianStressCauchy <|-- ComputeLagrangianObjectiveStress - ComputeLagrangianObjectiveStress <|-- ComputeHypoelasticStVenantKirchhoffStress - Material <|-- ComputeDeformGradBasedStress - CZMComputeGlobalTractionBase <|-- CZMComputeGlobalTractionTotalLagrangian -` ` ` - -## Code Snippets - -### 1. Pull-back of Cauchy stress to 2nd PK -The direct pull-back of Cauchy stress to 2nd PK is not explicitly shown as a single method. Instead, the framework often computes stresses in one form and then transforms them. For example, `ComputeLagrangianStressPK2` provides the 2nd PK stress and then derives the 1st PK stress from it. - -### 2. Push-forward of 2nd PK to Cauchy -The push-forward of 2nd PK stress to Cauchy stress is performed in `ComputeDeformGradBasedStress::computeQpStress()`: -` ` `cpp - _stress[_qp] = _deformation_gradient[_qp] * pk2 * _deformation_gradient[_qp].transpose() / - _deformation_gradient[_qp].det(); -` ` ` -And in `ComputeLagrangianStressPK1::computeQpCauchyStress()`: -` ` `cpp - _cauchy_stress[_qp] = _pk1_stress[_qp] * _F[_qp].transpose() / _F[_qp].det(); -` ` ` - -### 3. `RankTwoTensor` class methods -The `RankTwoTensor` class itself does not expose methods like `rotate()`, `pushForward()`, or `pullBack()` for general tensor transformations. These operations are typically handled at a higher level within material models, where the context of deformation gradient and Jacobian is available. - -### 4. Elasticity tensor transformation -The push-forward of the 4th-order elasticity tensor is shown in `ComputeHypoelasticStVenantKirchhoffStress::computeQpSmallStress()`: -` ` `cpp - const RankTwoTensor F = _def_grad[_qp]; - const Real J = F.det(); - const RankFourTensor FF = F.times(F); - const RankFourTensor FtFt = F.times(F); - const RankFourTensor C0 = _elasticity_tensor[_qp]; - const RankFourTensor C = FF * C0 * FtFt / J; -` ` ` - -### 5. Tangent modulus transformation for consistent linearization in total Lagrangian -MOOSE handles the tangent modulus transformation for consistent linearization in total Lagrangian formulations through the `_pk1_jacobian` property in `ComputeLagrangianStressBase` and its derivatives in subclasses. For example, `ComputeLagrangianStressPK2::computeQpPK1Stress()` calculates `_pk1_jacobian` based on `_C[_qp]` (2nd PK tangent) and the deformation gradient. The `TotalLagrangianStressDivergenceBase` kernel then uses this `_pk1_jacobian` for its computations. - -### 7. Material vs spatial descriptions -MOOSE converts back and forth between material (reference) and spatial (current) descriptions. The `ComputeLagrangianStressBase` class and its derivatives are designed to handle both Cauchy stress (spatial) and 1st Piola-Kirchhoff stress (material), along with their respective Jacobians. This allows for flexibility in material model implementation while providing the necessary quantities for both total and updated Lagrangian kernels. For instance, `ComputeLagrangianStressCauchy` computes Cauchy stress and then wraps it to get 1st PK stress, - - -## Stress measures and conversions in MOOSE - -MOOSE's Solid Mechanics module computes and converts between several stress and strain measures, primarily focusing on Cauchy stress, 1st Piola-Kirchhoff (PK1) stress, and 2nd Piola-Kirchhoff (PK2) stress, along with Green-Lagrange strain. The conversions are handled within a hierarchy of material classes, specifically `ComputeLagrangianStressBase` and its derivatives, which implement the necessary transformations based on whether large or small deformation kinematics are used . - -## Stress Measures and Conversions - -### 1. Cauchy stress $\sigma$ (true stress) -The Cauchy stress is a primary output in MOOSE, particularly when using classes derived from `ComputeLagrangianStressCauchy` . It is stored as a `MaterialProperty` named `_cauchy_stress` . - -#### Conversion from 1st Piola-Kirchhoff stress to Cauchy stress -When `_large_kinematics` is true, the Cauchy stress is computed from PK1 stress using the deformation gradient $F$ and its determinant $J$ (which is `_F[_qp].det()`): -$$ -\sigma = \frac{1}{J} P F^T \quad (1) -$$ -This conversion is implemented in `ComputeLagrangianStressPK1::computeQpCauchyStress()` . For small deformations, Cauchy stress is considered equivalent to PK1 stress . - -### 2. 1st Piola-Kirchhoff stress $P$ -The 1st Piola-Kirchhoff stress is also a primary output, especially for total Lagrangian formulations . It is stored as `_pk1_stress` . - -#### Conversion from Cauchy stress to 1st Piola-Kirchhoff stress -When `_large_kinematics` is true, PK1 stress is computed from Cauchy stress using the deformation gradient $F$ and its inverse $F^{-1}$ (represented by `_inv_def_grad`) and determinant $J$: -$$ -P = J \sigma F^{-T} \quad (2) -$$ -This conversion is implemented in `ComputeLagrangianStressCauchy::computeQpPK1Stress()` . For small deformations, PK1 stress is considered equivalent to Cauchy stress . - -#### Conversion from 2nd Piola-Kirchhoff stress to 1st Piola-Kirchhoff stress -When `_large_kinematics` is true, PK1 stress is computed from PK2 stress using the deformation gradient $F$: -$$ -P = F S \quad (3) -$$ -This conversion is implemented in `ComputeLagrangianStressPK2::computeQpPK1Stress()` . For small deformations, PK1 stress is considered equivalent to PK2 stress . - -### 3. 2nd Piola-Kirchhoff stress $S$ -The 2nd Piola-Kirchhoff stress is used for total Lagrangian formulations and is stored as `_S` . Classes like `ComputeNeoHookeanStress` and `ComputeStVenantKirchhoffStress` directly compute PK2 stress. - -### 4. Kirchhoff stress $\tau = J \sigma$ -The Kirchhoff stress is mentioned in the context of Simo-Hughes J2 plasticity . While not explicitly stored as a `MaterialProperty`, it is computed within the `ComputeSimoHughesJ2PlasticityStress` class . - -### 5. Mandel stress $M_e = C^e S^e = F^{eT} \tau F^{e-T}$ -The Mandel stress is not directly computed or stored as a `MaterialProperty` in the provided context. However, `MandelConverter` is included in `ComputeLagrangianObjectiveCustomStress.h` , suggesting its potential use for conversions related to custom material models. - -## Strain Measures - -### 6. Green-Lagrange strain $E = \frac{1}{2}(F^T F - I)$ -MOOSE computes the Green-Lagrange strain. It is explicitly calculated in `ComputeLagrangianStressPK2::computeQpPK1Stress()` and stored as `_E` . `ADComputeGreenLagrangeStrain` is a dedicated class for defining this strain tensor . The Almansi strain is not explicitly mentioned as being computed. - -### 7. Logarithmic (Hencky) strain: $\ln(U)$ -Logarithmic strain is available in MOOSE. It is referred to as "mechanical_strain" and represents the integrated deformation rate . It is used as an input to stress computation classes like `ComputeLagrangianObjectiveStress` . - -## Conversion Handling - -Conversions between stress measures are handled through a hierarchy of material classes, primarily `ComputeLagrangianStressBase` and its derived classes (`ComputeLagrangianStressCauchy`, `ComputeLagrangianStressPK1`, `ComputeLagrangianStressPK2`). These classes define virtual methods for computing specific stress measures and then wrap these to provide other required stress forms . The conversions are performed "ad-hoc" within these material models, often with conditional logic based on the `_large_kinematics` flag to switch between large and small deformation formulations . - -### Classes & Methods: - -* `ComputeLagrangianStressBase` : Base class for Lagrangian stress computations, defining the interface for Cauchy and 1st PK stress and their Jacobians . - * `computeQpStressUpdate()`: Virtual method to be implemented by derived classes for stress updates . -* `ComputeLagrangianStressCauchy` : Implements Cauchy stress update and wraps it to provide 1st PK stress . - * `computeQpPK1Stress()`: Converts Cauchy stress to 1st PK stress . -* `ComputeLagrangianStressPK1` : Implements 1st PK stress update and wraps it to provide Cauchy stress . - * `computeQpCauchyStress()`: Converts 1st PK stress to Cauchy stress . -* `ComputeLagrangianStressPK2` : Implements 2nd PK stress update and wraps it to provide 1st PK stress . - * `computeQpPK1Stress()`: Converts 2nd PK stress to 1st PK stress and computes Green-Lagrange strain . -* `ADComputeGreenLagrangeStrain` : Defines the Green-Lagrange strain tensor . -* `ComputeSimoHughesJ2PlasticityStress` : Computes Kirchhoff stress as part of its algorithm . - -### Relationships: - -` ` `mermaid -classDiagram - class Material - class ComputeLagrangianStressBase - class ComputeLagrangianStressCauchy - class ComputeLagrangianStressPK1 - class ComputeLagrangianStressPK2 - class ComputeLagrangianObjectiveStress - class ComputeNeoHookeanStress - class ComputeStVenantKirchhoffStress - class ComputeSimoHughesJ2PlasticityStress - class ADComputeGreenLagrangeStrain - - Material <|-- ComputeLagrangianStressBase - ComputeLagrangianStressBase <|-- ComputeLagrangianStressCauchy - ComputeLagrangianStressBase <|-- ComputeLagrangianStressPK1 - ComputeLagrangianStressPK1 <|-- ComputeLagrangianStressPK2 - ComputeLagrangianStressCauchy <|-- ComputeLagrangianObjectiveStress - ComputeLagrangianStressPK2 <|-- ComputeNeoHookeanStress - ComputeLagrangianStressPK2 <|-- ComputeStVenantKirchhoffStress - ComputeLagrangianStressPK1 <|-- ComputeSimoHughesJ2PlasticityStress - - ComputeLagrangianStressBase : +_cauchy_stress - ComputeLagrangianStressBase : +_pk1_stress - ComputeLagrangianStressPK2 : +_E (Green-Lagrange strain) - ComputeLagrangianStressPK2 : +_S (2nd PK stress) - ComputeLagrangianStressBase : +_large_kinematics - ComputeLagrangianStressBase : +computeQpStressUpdate() - ComputeLagrangianStressCauchy : +computeQpPK1Stress() - ComputeLagrangianStressPK1 : +computeQpCauchyStress() - ComputeLagrangianStressPK2 : +computeQpPK1Stress() - ComputeLagrangianStressPK2 : + - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-output-postprocessing.md b/packages/akms/src/akms/_bundled/global_nodes/moose-output-postprocessing.md deleted file mode 100644 index 1ceddc9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-output-postprocessing.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: moose-output-postprocessing -title: MOOSE Output System and Postprocessing -domain: architecture -subdomain: procedural -tags: -- output -- exodus -- postprocessor -- aux-variable -- checkpoint -- restart -- VTK -- CSV -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-object-factory - type: requires - weight: 0.6 - note: Uses MOOSE object factory and registration pattern -- to: cm-verification - type: implements - weight: 0.5 - note: Postprocessors and AuxKernels compute verification quantities ---- - -# MOOSE Output System and Postprocessing - -Framework knowledge node covering 1 aspect(s) of Output System and Postprocessing. - -## Output system and postprocessing architecture - -MOOSE's output and postprocessing system is designed to extract and present simulation data in various formats, including scalar values, tabular data, and visualization fields . This system is built upon a hierarchy of classes that manage different output types and data processing mechanisms . - -## Output Types: `Exodus`, `CSV`, `VTK`, `Console`, `Checkpoint` - -MOOSE provides several output types, each handled by a specific class derived from `AdvancedOutput` . These output objects can be configured in the `[Outputs]` block of the input file . - -### Classes & Methods: -* `AdvancedOutput` : Base class for advanced output functionalities, managing various output lists and execution flags . -* `Exodus` : Outputs simulation data to ExodusII files, a common format for finite element analysis results . -* `CSV` : Outputs data in a comma-separated value format, often used for tabular data from Postprocessors and VectorPostprocessors . -* `VTK` : Outputs data in VTK format for visualization in tools like ParaView . -* `Console` : Prints output directly to the console, useful for quick checks and performance logs . -* `Checkpoint` : Saves the complete state of the simulation for restart and recovery purposes . - -## `Postprocessor` - Scalar Derived Quantities - -`Postprocessor` objects compute single scalar (`Real`) values from simulation data . They are used for various aggregate calculations like integrals, averages, or sampled values . - -### Classes & Methods: -* `Postprocessor` : Base class for all scalar postprocessors . - * `initialize()` : Called before every execution to reset accumulated quantities . - * `execute()` : Defines the operation performed on a per-element, side, or node basis . - * `getValue()` : Returns the final scalar value of the postprocessor . -* `GeneralPostprocessor` : `execute()` is called once per execution flag . -* `NodalPostprocessor` : `execute()` is called for each node in the mesh . -* `ElementalPostprocessor` : `execute()` is called for each element in the mesh . -* `SidePostprocessor` : `execute()` is called for each side on a boundary . -* `InternalSidePostprocessor` : `execute()` is called for each internal side . - -### Execution Timing: -Postprocessors can be configured to execute at varying times during a simulation using the `execute_on` parameter, such as during initialization (`INITIAL`) or at the end of each time step (`timestep_end`) . They are also automatically restored to their previous value if a timestep is rejected . - -### Pattern for Adding a New Postprocessed Quantity: -1. Create a new C++ class inheriting from an appropriate `Postprocessor` base class (e.g., `GeneralPostprocessor`, `NodalPostprocessor`) . -2. Override the `execute()` method to perform the calculation . -3. Override the `getValue()` method to return the computed scalar result . -4. Implement `initialize()` and `finalize()` for parallel communication and aggregation, if necessary . -5. Register the new `Postprocessor` in the MOOSE input system. - -## `VectorPostprocessor` - Tabular Data Output - -`VectorPostprocessor` (VPP) objects compute multiple related values, outputting them as one or many vectors . They are suitable for sampling solution fields along a line or tracking values over time . - -### Classes & Methods: -* `VectorPostprocessor` : Base class for postprocessors that produce a vector of values . - * `declareVector(const std::string & vector_name)` : Registers a new vector to be filled and output . - * `getVectorNames()` : Returns the names of the vectors associated with the object . -* `VectorPostprocessorValue` : Represents a vector of real values managed by the VPP system . - -### Output: -VPP data is typically output to CSV files, with separate files for each vector and timestep unless `contains_complete_history = true` is set . VPPs are required to create their complete vectors on processor zero, using `_communicator` for reduction . - -## `AuxVariable` + `AuxKernel` - Visualization Fields - -`AuxVariable` and `AuxKernel` are used to compute and store auxiliary fields, often for visualization purposes like von Mises stress or plastic strain . `AuxVariables` are defined in the input file and `AuxKernels` define how these variables are computed . - -### Classes & Methods: -* `AuxiliarySystem` : Manages auxiliary variables and `AuxKernel` objects . -* `AuxKernel` : Base class for computing scalar auxiliary values . - * `computeValue()` : Overridden method to define the computation of the auxiliary value . -* `VectorAuxKernel` : For computing vector auxiliary values . -* `ArrayAuxKernel` : For computing array auxiliary values . -* `AuxVariable` : Represents an auxiliary variable, defined in the `[AuxVariables]` block . - -`AuxKernels` can be nodal or elemental, depending on the `family` of the `AuxVariable` they operate on . Nodal `AuxKernels` compute values at each node, while elemental `AuxKernels` compute values at quadrature points within each element . - -## `ElementalVariableValue` vs `NodalVariableValue` - Field Type Determination - -The field type (nodal or elemental) for variables is determined by the `family` parameter of the `MooseVariable` . -* `MooseVariableFE` : Represents a finite element variable, storing solution values, gradients, and time derivatives < - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-output-system.md b/packages/akms/src/akms/_bundled/global_nodes/moose-output-system.md deleted file mode 100644 index b7f82d3..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-output-system.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: moose-output-system -title: MOOSE Output system and postprocessing architecture -domain: architecture -subdomain: procedural -tags: -- output -- exodus -- postprocessor -- aux-variable -- checkpoint -- restart -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-output-postprocessing - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-output-postprocessing ---- - -# MOOSE Output system and postprocessing architecture - -MOOSE's output and postprocessing system is designed to extract and present simulation data in various formats, including scalar values, tabular data, and visualization fields . This system is built upon a hierarchy of classes that manage different output types and data processing mechanisms . - -## Output Types: `Exodus`, `CSV`, `VTK`, `Console`, `Checkpoint` - -MOOSE provides several output types, each handled by a specific class derived from `AdvancedOutput` . These output objects can be configured in the `[Outputs]` block of the input file . - -### Classes & Methods: -* `AdvancedOutput` : Base class for advanced output functionalities, managing various output lists and execution flags . -* `Exodus` : Outputs simulation data to ExodusII files, a common format for finite element analysis results . -* `CSV` : Outputs data in a comma-separated value format, often used for tabular data from Postprocessors and VectorPostprocessors . -* `VTK` : Outputs data in VTK format for visualization in tools like ParaView . -* `Console` : Prints output directly to the console, useful for quick checks and performance logs . -* `Checkpoint` : Saves the complete state of the simulation for restart and recovery purposes . - -## `Postprocessor` - Scalar Derived Quantities - -`Postprocessor` objects compute single scalar (`Real`) values from simulation data . They are used for various aggregate calculations like integrals, averages, or sampled values . - -### Classes & Methods: -* `Postprocessor` : Base class for all scalar postprocessors . - * `initialize()` : Called before every execution to reset accumulated quantities . - * `execute()` : Defines the operation performed on a per-element, side, or node basis . - * `getValue()` : Returns the final scalar value of the postprocessor . -* `GeneralPostprocessor` : `execute()` is called once per execution flag . -* `NodalPostprocessor` : `execute()` is called for each node in the mesh . -* `ElementalPostprocessor` : `execute()` is called for each element in the mesh . -* `SidePostprocessor` : `execute()` is called for each side on a boundary . -* `InternalSidePostprocessor` : `execute()` is called for each internal side . - -### Execution Timing: -Postprocessors can be configured to execute at varying times during a simulation using the `execute_on` parameter, such as during initialization (`INITIAL`) or at the end of each time step (`timestep_end`) . They are also automatically restored to their previous value if a timestep is rejected . - -### Pattern for Adding a New Postprocessed Quantity: -1. Create a new C++ class inheriting from an appropriate `Postprocessor` base class (e.g., `GeneralPostprocessor`, `NodalPostprocessor`) . -2. Override the `execute()` method to perform the calculation . -3. Override the `getValue()` method to return the computed scalar result . -4. Implement `initialize()` and `finalize()` for parallel communication and aggregation, if necessary . -5. Register the new `Postprocessor` in the MOOSE input system. - -## `VectorPostprocessor` - Tabular Data Output - -`VectorPostprocessor` (VPP) objects compute multiple related values, outputting them as one or many vectors . They are suitable for sampling solution fields along a line or tracking values over time . - -### Classes & Methods: -* `VectorPostprocessor` : Base class for postprocessors that produce a vector of values . - * `declareVector(const std::string & vector_name)` : Registers a new vector to be filled and output . - * `getVectorNames()` : Returns the names of the vectors associated with the object . -* `VectorPostprocessorValue` : Represents a vector of real values managed by the VPP system . - -### Output: -VPP data is typically output to CSV files, with separate files for each vector and timestep unless `contains_complete_history = true` is set . VPPs are required to create their complete vectors on processor zero, using `_communicator` for reduction . - -## `AuxVariable` + `AuxKernel` - Visualization Fields - -`AuxVariable` and `AuxKernel` are used to compute and store auxiliary fields, often for visualization purposes like von Mises stress or plastic strain . `AuxVariables` are defined in the input file and `AuxKernels` define how these variables are computed . - -### Classes & Methods: -* `AuxiliarySystem` : Manages auxiliary variables and `AuxKernel` objects . -* `AuxKernel` : Base class for computing scalar auxiliary values . - * `computeValue()` : Overridden method to define the computation of the auxiliary value . -* `VectorAuxKernel` : For computing vector auxiliary values . -* `ArrayAuxKernel` : For computing array auxiliary values . -* `AuxVariable` : Represents an auxiliary variable, defined in the `[AuxVariables]` block . - -`AuxKernels` can be nodal or elemental, depending on the `family` of the `AuxVariable` they operate on . Nodal `AuxKernels` compute values at each node, while elemental `AuxKernels` compute values at quadrature points within each element . - -## `ElementalVariableValue` vs `NodalVariableValue` - Field Type Determination - -The field type (nodal or elemental) for variables is determined by the `family` parameter of the `MooseVariable` . -* `MooseVariableFE` : Represents a finite element variable, storing solution values, gradients, and time derivatives < - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-fieldsplit.md b/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-fieldsplit.md deleted file mode 100644 index 2b845bc..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-fieldsplit.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -id: moose-petsc-fieldsplit -title: MOOSE Custom PETSc solver configurations and fieldsplit -domain: solver -subdomain: procedural -tags: -- fieldsplit -- schur-complement -- MUMPS -- SuperLU -- nested-solvers -- block-preconditioning -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-petsc-interface - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-petsc-interface ---- - -# MOOSE Custom PETSc solver configurations and fieldsplit - -MOOSE extensively leverages PETSc for advanced solver configurations, particularly through its `FieldSplitPreconditioner` and `Split` objects, allowing for detailed control over block preconditioning, Schur complement methods, and custom solver types. It also provides mechanisms for PETSc monitoring and integration with external packages. - -## PETScFieldSplit -MOOSE sets up PETSc's `PCFIELDSPLIT` for block preconditioning using the `FieldSplitPreconditioner` class . This preconditioner allows for custom preconditioning for each nonlinear variable in the numerical system . The `FieldSplitPreconditioner` is initialized with a `topsplit` parameter, which defines the entry point for the splitting hierarchy . - -The `FieldSplitPreconditioner` constructs a `CouplingMatrix` to define how variables couple . By default, `full=true` creates a fully coupled Jacobian matrix, but users can specify `off_diag_row` and `off_diag_column` to define custom couplings . The `_nl.useFieldSplitPreconditioner(this)` call registers the preconditioner with the nonlinear system . - -### MOOSE Input Syntax -An example of setting up a `FieldSplitPreconditioner` for variables 'u' and 'v' with an additive splitting type: -` ` `ini -[Preconditioning] - [FSP] - type = FSP - topsplit = 'uv' - [uv] - splitting = 'u v' - splitting_type = additive - [] - [u] - symbol_names = 'u' - petsc_options_iname = '-pc_type -ksp_type' - petsc_options_value = ' hypre preonly' - [] - [v] - symbol_names = 'v' - petsc_options_iname = '-pc_type -ksp_type' - petsc_options_value = ' hypre preonly' - [] - [] -` ` ` - -## Schur Complement Preconditioners -MOOSE can use PETSc's Schur factorization for saddle-point problems. The `Split` object, which is used within `FieldSplitPreconditioner`, has parameters to control Schur complement behavior . - -**Parameters:** -* `splitting_type = schur`: Specifies that the splitting should use Schur factorization . -* `schur_type = "diag" | "upper" | "lower" | "full"`: Controls the type of Schur complement factorization . -* `schur_pre = "S" | "Sp" | "A11"`: Determines which preconditioning matrix to use with $S = D - CA^{-1}B$ . - -The `NavierStokesProblem` specifically demonstrates the use of Schur complement preconditioning, including the Least Squares Commutator (LSC) preconditioner . It can configure the Schur complement preconditioner to be a pressure mass matrix or an LSC preconditioner . - -## Custom KSP/PC Types -Users can specify nested solver configurations through the `Split` objects within the `[Preconditioning]` block . Each sub-split can have its own `petsc_options_iname` and `petsc_options_value` parameters, allowing for fine-grained control over the `KSP` and `PC` types for different blocks . For example, you can set `hypre` for `pc_type` and `preonly` for `ksp_type` for a specific variable's subsolver . - -## PETSc DM Integration -MOOSE uses a custom `DMMoose` object for structured solver information, particularly in the context of `FieldSplitPreconditioner` . The `FieldSplitPreconditioner::createMooseDM` method creates and sets up this `DM` object, associating it with the nonlinear system and its `DofMap` . This `DM` object is then set on the `SNES` solver . - -## Matrix-Free Preconditioners -MOOSE supports matrix-free Jacobian-vector products, especially with the `PJFNK` (Preconditioned Jacobian-Free Newton Krylov) solve type . While the documentation mentions `PCShell` in the context of custom preconditioners, the provided snippets do not explicitly show how users can provide a custom `PCShell` through MOOSE input files. However, the `PCApply_MoosePC` function in `SlepcSupport.C` suggests a mechanism for applying a MOOSE-defined preconditioner within PETSc, which could potentially be extended to a `PCShell` . - -## PETSc Monitoring -PETSc monitoring options like `-ksp_monitor`, `-snes_monitor`, and `-log_view` can be enabled through MOOSE input files using the `petsc_options` parameter in the `Executioner` block or within `[Preconditioning]` blocks . - -**Parameters:** -* `petsc_options = '-ksp_monitor -snes_monitor -log_view'`: Directly sets these PETSc flags . -* `petsc_options_iname = '-ksp_monitor'` and `petsc_options_value = ''`: Can also be used for flags . - -These options are processed by `Moose::PetscSupport::storePetscOptions` , which adds them to a `PetscOptions` object that is then used to set PETSc options . - -## External Packages through PETSc -MOOSE can configure external packages like MUMPS, SuperLU, and HYPRE (ML is not explicitly mentioned in the provided context but HYPRE is) through PETSc options in the input file . - -**Parameters:** -* `petsc_options_iname = '-pc_type -pc_hypre_type'` -* `petsc_options_value = 'hypre boomeramg'` - -For SuperLU, specific options like `-mat_superlu_dist_replacetinypivot` can be set . These are passed via the `petsc_options_iname` and `petsc_options_value` parameters, which are then processed by `Moose::PetscSupport::storePetscOptions` . - -## Classes & Methods -* `FieldSplitPreconditioner::validParams()`: Registers valid input parameters for the `FieldSplitPreconditioner` . -* `FieldSplitPreconditioner::FieldSplitPreconditioner()`: Constructor that initializes the preconditioner, sets up the `CouplingMatrix`, and registers itself with the nonlinear system . -* `FieldSplitPreconditioner::createMooseDM()`: Creates and configures the `DMMoose` object for the field split . -* `Split::validParams()`: Registers valid input parameters for a `Split` object, including options for splitting type, Schur type, and PETSc options . -* `Split::setup()`: Configures the PETSc options for a given split, including setting the splitting type, Schur type, and recursively setting up sub-splits . -* `Moose::PetscSupport::storePetscOptions()`: Processes and stores PETSc options from MOOSE input parameters . -* `NavierStokesProblem::setupLSCMatrices()`: Sets up the Least Squares Commutator (LSC) preconditioner for the Schur complement . -* `PCApply_MoosePC()`: A PETSc callback function that applies a MOOSE-defined preconditioner . - -## Parameters -* `topsplit = 'string'`: (Type: `std::string`, Required) The name of the top-level split, which defines the entry point for the splitting hierarchy . -* `full = true | false`: (Type: `bool`, Default: `true`) If `true`, a full coupling Jacobian matrix is constructed. If `false`, `off_diag_row` and `off_diag_column` must be specified . -* `off_diag_row = 'vector'`: (Type: `std::vector`) Specifies rows for off-diagonal coupling . -* `off_diag_column = 'vector'`: (Type: `std::vector`) Specifies columns for off-diagonal coupling . -* `splitting = 'vector'`: (Type: `std::vector`) The names of the sub-splits (subsystems) in the decomposition of this split . -* `splitting_type = "additive" | "multiplicative" | "symmetric_multiplicative" | "schur"`: (Type: `MooseEnum`, Default: `additive`) The type of split decomposition . -* `schur_type = "diag" | "upper" | "lower" | "full"`: (Type: `MooseEnum`, Default: `full`) Type of Schur complement factorization . -* `schur_pre = "S" | "Sp" | "A11"`: (Type: `MooseEnum`, Default: `S`) Type of Schur complement preconditioner matrix . -* `petsc_options = 'MultiMooseEnum'`: (Type: `MultiMooseEnum`) Singleton PETSc options (flags) . -* `petsc_options_iname = 'MultiMooseEnum'`: (Type: `MultiMooseEnum`) Names of PETSc name/value pairs . -* `petsc_options_value = 'vector'`: (Type: `std::vector`) - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-gpu.md b/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-gpu.md deleted file mode 100644 index 7f06789..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-gpu.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: moose-petsc-gpu -title: MOOSE GPU acceleration and PETSc GPU backends in MOOSE -domain: solver -subdomain: procedural -tags: -- GPU -- CUDA -- Kokkos -- cuSPARSE -- VecType -- MatType -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-petsc-interface - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-petsc-interface ---- - -# MOOSE GPU acceleration and PETSc GPU backends in MOOSE - -MOOSE supports GPU-accelerated linear algebra primarily through its integration with PETSc and Kokkos. You can configure MOOSE to leverage CUDA or HIP backends for PETSc, and it also provides a Kokkos-MOOSE framework for GPU-accelerated element assembly and other operations. - -## PETSc GPU Backends -MOOSE supports PETSc with CUDA and HIP backends. The configuration for these is done when building PETSc, by including flags like `--with-cuda` or `--with-hip`. MOOSE also checks for `PETSC_HAVE_KOKKOS`, `PETSC_HAVE_CUDA`, and `PETSC_HAVE_HIP` during its own configuration. - -## `VecType` and `MatType` for GPU -MOOSE can utilize PETSc's GPU-specific `VecType` and `MatType` through its `libMesh` dependency. When PETSc is built with CUDA or HIP support, `libMesh` will use the appropriate GPU-enabled vector and matrix types (e.g., `VECCUDA`, `MATAIJCUSPARSE`). The `Moose::Kokkos::Matrix` class specifically handles `libMesh::PetscMatrix` objects and can create device-side storage for matrix values if Kokkos GPU capabilities are enabled. - -## Changes Needed in MOOSE to Run on GPU -Running MOOSE on GPU is not entirely transparent and requires specific configurations and code modifications for GPU-accelerated components. -1. **PETSc Configuration**: You need to build PETSc with GPU support (e.g., `--with-cuda`). -2. **MOOSE Configuration**: MOOSE itself needs to be configured with `--with-kokkos` to enable Kokkos-MOOSE capabilities. -3. **Code Modification for Kokkos-MOOSE**: For MOOSE objects to run on GPU using Kokkos, they need to be specifically written or adapted for the Kokkos-MOOSE framework. This involves using `KOKKOS_FUNCTION` for GPU-callable functions, using `Moose::Kokkos::Array` and other Kokkos-specific data structures for device memory, and implementing static polymorphism via CRTP instead of virtual functions. - -## Matrix-Free GPU Operations -The documentation indicates that `MFEMProblem` allows problem assembly and solution on GPU architectures, which implies that matrix-free operations like the JFNK Jv product could potentially run on the GPU if the residual evaluations are implemented for the device. However, explicit details on JFNK Jv product running on GPU are not provided in the given context. - -## Element Assembly on GPU -Yes, there is active work on GPU-accelerated element assembly in MOOSE via Kokkos. The Kokkos-MOOSE framework provides GPU versions of `Kernels`, `NodalKernels`, `BCs`, `Materials`, `AuxKernels`, and `Functions`. These Kokkos objects are designed to resemble their CPU counterparts but require specific GPU programming practices, such as using `KOKKOS_FUNCTION` and `Moose::Kokkos::Array`. - -## libMesh's Role -`libMesh` acts as an abstraction layer for the linear algebra backend, including PETSc. MOOSE interacts with PETSc primarily through `libMesh`. When PETSc is configured with GPU support, `libMesh` will automatically use the GPU-enabled PETSc functionalities. However, for element assembly and other MOOSE-specific operations to run on the GPU, MOOSE also provides its own Kokkos-based framework (`Kokkos-MOOSE`) which requires direct interaction with Kokkos programming paradigms. - -## Current Status -Currently, Kokkos-MOOSE is available for preliminary testing with NVIDIA GPUs. It supports GPU versions of `Kernels`, `NodalKernels`, `BCs`, `Materials`, `AuxKernels`, and `Functions`. Support for AMD and Intel GPUs is planned for the future. Some limitations exist, such as the lack of support for coupling with scalar variables and automatic differentiation in Kokkos-MOOSE kernels, and boundary-restricted elemental `AuxKernels`. - -## Performance -The provided context does not explicitly state for what problem sizes GPU acceleration becomes beneficial in MOOSE. However, general GPU programming principles suggest that GPUs are most effective for problems with high parallelism and large data sets, where the overhead of data transfer to and from the device is amortized by the computational speedup. - -## Configuration Flags and PETSc Options -### MOOSE Configuration Flags -* `--with-kokkos`: Enables Kokkos-MOOSE capabilities. - -### PETSc Configuration Flags -When building PETSc, you can use the following options: -* `--with-cuda`: Enables CUDA support. -* `--with-hip`: Enables HIP support. -* `--with-cuda-arch=[arch]`: Specifies the CUDA GPU architecture (e.g., `80` for `sm_80`). -* `--with-hip-arch=[arch]`: Specifies the HIP GPU architecture (e.g., `gfx908`). - -## MOOSE-specific GPU Classes or Interfaces -### Classes & Methods -* `Moose::Kokkos::Array`: A template class for multi-dimensional arrays designed for GPU access, supporting creation on host, device, or both, and explicit data synchronization. -* `Moose::Kokkos::JaggedArray`: A data container for jagged arrays on GPU. -* `Moose::Kokkos::Map`: A hash map implementation for GPU, using FNV-1a hash algorithm. -* `Moose::Kokkos::ReferenceWrapper`: A template class to hold a reference to a CPU variable and provide an up-to-date value on GPU, synchronizing via the copy constructor. -* `Moose::Kokkos::Scalar`: Derived from `Moose::Kokkos::ReferenceWrapper`, providing arithmetic operators for stored values. -* `Moose::Kokkos::Matrix::create(libMesh::SparseMatrix & matrix, const System & system)`: Creates a Kokkos-managed matrix from a `libMesh::PetscMatrix`, allocating device memory for values if GPU is enabled. -* `Moose::Kokkos::Kernel`: Base class for GPU-accelerated kernels, requiring `KOKKOS_FUNCTION` for hook methods like `computeQpResidual()`. - -### Code Snippets -**Example of `Moose::Kokkos::Array` wrapping a PETSc vector:** -` ` `cpp -PetscScalar * petsc_ptr; -PetscInt petsc_size; -VecGetArray(petsc_vector, &petsc_ptr); -VecGetLocalSize(petsc_vector, &petsc_size); - -Array vector; - -vector.createDevice(petsc_size); -vector.aliasHost(petsc_ptr); -vector.copyToDevice(); -` ` ` - -**Example of `KOKKOS_FUNCTION` usage in a Kokkos Kernel:** -` ` `cpp -KOKKOS_FUNCTION Real -KokkosDiffusion::computeQpResidual(const unsigned int i, - const unsigned int qp, - AssemblyDatum & datum) const -{ - return _grad_u(datum, qp) * _grad_test(datum, i, qp); -} -` ` ` - -## Notes -The `MFEMProblem` in MOOSE also offers GPU acceleration through the MFEM library, which can leverage CUDA or HIP. This is a separate but related path to GPU acceleration compared to the Kokkos-MOOSE framework. - -Wiki pages you might want to explore: -- [Executioner and Time Integration (idaholab/moose)](https://deepwiki.com/idaholab/moose#3.2) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-interface.md b/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-interface.md deleted file mode 100644 index 356c7b7..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-interface.md +++ /dev/null @@ -1,466 +0,0 @@ ---- -id: moose-petsc-interface -title: MOOSE PETSc Interface — Linear Operators, Matrix-Free, and GPU -domain: solver -subdomain: procedural -tags: -- PETSc -- linear-algebra -- matrix-free -- GPU -- CUDA -- Kokkos -- fieldsplit -- MUMPS -- SNES -- KSP -- preconditioner -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: large -reading_priority: full -akms_schema: v2 -edges: -- to: cm-solver-matrixfree - type: implements - weight: 0.8 - note: Implements PETSc interface for matrix-free and GPU solvers -- to: tgs-dom-linear-solvers - type: implements - weight: 0.7 - note: MOOSE-PETSc interface for linear solver configuration ---- - -# MOOSE PETSc Interface — Linear Operators, Matrix-Free, and GPU - -Framework knowledge node covering 4 aspect(s) of PETSc Interface — Linear Operators, Matrix-Free, and GPU. - -## MOOSE-PETSc linear algebra interface - -MOOSE leverages `libMesh` as an intermediary layer to interface with PETSc for linear algebra operations. `libMesh::PetscMatrix` and `libMesh::PetscVector` wrap the underlying PETSc data structures, and MOOSE's `NonlinearSystem` registers its residual and Jacobian computation routines with PETSc's SNES solver. - -## MOOSE to PETSc Interface Overview - -MOOSE's problem-solving architecture, centered around `FEProblemBase` and `NonlinearSystemBase`, orchestrates the definition, assembly, and solution of systems of equations . `libMesh` provides the finite element infrastructure and acts as a bridge to PETSc . - -` ` `mermaid -graph TD - subgraph "MOOSE" - A["FEProblemBase"] - B["NonlinearSystem"] - C["Assembly"] - end - - subgraph "libMesh" - D["NonlinearImplicitSystem"] - E["PetscMatrix"] - F["PetscVector"] - G["DofMap"] - end - - subgraph "PETSc" - H["SNES"] - I["Mat"] - J["Vec"] - end - - A --> B - B --> C - B --> D - D --> E - D --> F - D --> G - E --> I - F --> J - D -- "Registers callbacks" --> H - H -- "Calls back to" --> D -` ` ` - -## 1. Assembled Matrices and PETSc Mat Types - -MOOSE passes assembled matrices to PETSc through `libMesh::PetscMatrix` objects . `libMesh::PetscMatrix` wraps a PETSc `Mat` object . The specific `Mat` type (e.g., `MATAIJ`, `MATBAIJ`) is typically determined by PETSc's defaults or user-specified options . MOOSE allows users to specify the matrix type via the `petsc_options_iname` and `petsc_options_value` parameters, for example, `-mat_type aij` . - -## 2. `NonlinearSystem` → PETSc SNES Connection - -The `NonlinearSystem` in MOOSE registers its residual and Jacobian functions with PETSc's SNES solver through `libMesh::PetscNonlinearSolver` . - -### Residual Function Registration - -The residual function is registered with SNES via `DMSNESSetFunction` , which points to `SNESFunction_DMMoose` . `SNESFunction_DMMoose` then calls `DMMooseFunction` , which retrieves the MOOSE `NonlinearSystemBase` and invokes its residual computation routines . - -### Jacobian Function Registration - -Similarly, the Jacobian function is registered using `DMSNESSetJacobian` , which points to `SNESJacobian_DMMoose` . `SNESJacobian_DMMoose` calls `DMMooseJacobian` , which in turn obtains the `NonlinearSystemBase` and calls its Jacobian computation methods . For finite-differenced preconditioners, `SNESSetJacobian` can also be used with `SNESComputeJacobianDefault` or `MatFDColoringSetFunction` . - -## 3. `libMesh::PetscMatrix` and `libMesh::PetscVector` - -`libMesh::PetscMatrix` and `libMesh::PetscVector` are wrapper classes provided by `libMesh` that encapsulate PETSc's `Mat` and `Vec` data structures, respectively . They provide a `libMesh` interface while managing the underlying PETSc objects. For example, `PetscMatrix::mat()` returns the raw PETSc `Mat` pointer . - -## 4. Sparse Matrix Assembly - -MOOSE's element-level contributions (e.g., `_local_ke` from kernels) are assembled into the global PETSc `Mat` through `libMesh`'s assembly routines. These routines ultimately make calls to PETSc's `MatSetValues()` or similar functions to insert local matrix entries into the global sparse matrix . The `Assembly` class in MOOSE is responsible for gathering these contributions from various physics components . - -## 5. Matrix Preallocation - -MOOSE determines the sparsity pattern and preallocates the PETSc matrix during the setup phase. The `libMesh::DofMap` plays a crucial role in defining the global degrees of freedom and their connectivity, which is used to build the sparsity pattern . `MatCreate` and `MatSetSizes` are called, followed by `MatSetType` to specify the matrix type . For certain matrix types, `MatSetPreallocationCOO` can be used for efficient preallocation . - -## 6. Block Structure for Multi-Variable Problems - -For multi-variable problems, MOOSE primarily uses a monolithic matrix approach where all variables are part of a single system . However, it can leverage PETSc's block preconditioning capabilities, such as field-split preconditioners, to improve convergence . The `PetscDMMoose` utility provides functions like `DMMooseSetSplitNames` and `DMMooseSetSplitVars` to define these field splits for PETSc's `DM` objects . - -## 7. Exposing PETSc Options to the User - -MOOSE exposes PETSc options to the user through input file parameters: `petsc_options`, `petsc_options_iname`, and `petsc_options_value` . - -* `petsc_options`: Used for single-flag PETSc options (e.g., `-snes_mf`) . -* `petsc_options_iname`: Specifies the names of PETSc key-value pairs (e.g., `-pc_type`) . -* `petsc_options_value`: Provides the corresponding values for the `petsc_options_iname` parameters (e.g., `hypre`) . - -These parameters allow for raw PETSc command-line pass-through, enabling users to fine-tune PETSc's solvers and preconditioners . The `PetscSupport::addPetscFlagsToPetscOptions` and `PetscSupport::addPetscPairsToPetscOptions` functions process these input parameters and set the options within PETSc . - -## Classes & Methods - -* `NonlinearSystem::compute_jacobian()`: A static function called by `libMesh` to compute the Jacobian matrix . -* `NonlinearSystem::setupColoringFiniteDifferencedPreconditioner()`: Configures PETSc for finite-differenced Jacobian computation using coloring . -* `DMMooseFunction()`: A static PETSc callback function that computes the residual for a `DM` object . -* `SNESFunction_DMMoose()`: The PETSc SNES callback for residual computation, which calls `DMMooseFunction` . -* `DMMooseJacobian()`: A static PETSc callback function that computes the Jacobian matrix for a `DM` object . -* `SNESJacobian_DMMoose()`: The PETSc SNES callback for Jacobian computation, which calls `DMMooseJacobian` . -* `DMCreateMoose()`: Creates a MOOSE-specific PETSc `DM` object . -* `DMCreateMatrix_Moose()`: Creates a PETSc `Mat` object associated with a MOOSE `DM` . -* `PetscSupport::petscSetOptions()`: Sets PETSc options from MOOSE's `PetscOptions` object . -* `PetscSupport::addPetscFlagsToPetscOptions()`: Populates `PetscOptions` with single-flag PETSc options from input parameters . -* `PetscSupport::addPetscPairsToPetscOptions()`: Populates `PetscOptions` with key-value pair PETSc options from input parameters . - -## Parameters - -* `solve_type = PJFNK | JFNK | NEWTON | FD | LINEAR`: Controls the nonlinear solver method . -* `mffd_type = wp | ds`: Specifies the finite differencing type for Jacobian-free solves . -* `petsc_options = `: Singleton PETSc options (e.g., `-snes_ksp_ew`) . -* `petsc_options_iname = `: Names of PETSc name/value pairs (e.g., `-pc_type`) . -* `petsc_options_value = `: Values corresponding to `petsc_options_iname` (e.g., `hypre`) . - -## MOOSE Input Syntax - -` ` `ini -[Executioner] - type = Steady - solve_type = PJFNK - petsc_options_iname = '-pc_type -pc_hypre_type' - petsc_options_value = 'hypre boomeramg' -[] -` ` ` - - -## Notes - -The interaction between MOOSE and PETSc is primarily mediated by `libMesh`. `libMesh` provides the `PetscMatrix` and `PetscVector` wrappers, and its `NonlinearImplicitSystem` registers the necessary callbacks with PETSc's SNES solver. The `PetscDMMoose` utility plays a significant role in setting up the PETSc `DM` object and connecting it to MOOSE's `NonlinearSystemBase` for residual and Jacobian evaluations. Users have extensive control over PETSc's behavior through input file parameters, allowing for flexible solver and preconditioner configurations. - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - - -## Matrix-free operations and JFNK implementation details - -MOOSE implements matrix-free Jacobian-vector products for JFNK by leveraging PETSc's `MatShell` and `MatMFFD` functionalities. It registers a custom matrix-vector product routine with PETSc, which internally calls MOOSE's residual evaluation function. For preconditioning, MOOSE can either assemble a separate matrix or operate in a fully matrix-free mode. - -## Classes & Methods -* `Moose::SlepcSupport::setOperationsForShellMat(EigenProblem & eigen_problem, Mat mat, bool eigen)`: Sets the matrix-vector product operation for a PETSc `MatShell` based on whether it's for an eigen problem or not. -* `Moose::SlepcSupport::mooseMatMult_NonEigen(Mat mat, Vec x, Vec r)`: The callback function for `MATOP_MULT` when the `MatShell` represents the non-eigen part of the Jacobian. It evaluates the residual. -* `NonlinearSystem::setupFiniteDifferencedPreconditioner()`: Configures the finite-differenced preconditioner, which can be either "coloring" or "standard". -* `SNESSetJacobian()`: A PETSc function used to set the Jacobian evaluation function for the nonlinear solver. - -## Equations -The Jacobian-vector product for JFNK is approximated using a finite-difference formula: -$$ -\mathbf{J}(\mathbf{u}^{i-1}) \mathbf{y} \approx \frac{\mathbf{R}(\mathbf{u}^{i-1} + \epsilon \mathbf{y}) - \mathbf{R}(\mathbf{u}^{i-1})}{\epsilon} \quad (1) -$$ -For preconditioned JFNK (PJFNK), the action of the preconditioned Jacobian is approximated as: -$$ -\mathbf{J} \mathbf{P}^{-1}\mathbf{v} \approx \frac{\mathbf{R}(\mathbf{u} + \epsilon \mathbf{P}^{-1}\mathbf{v}) - \mathbf{R}(\mathbf{u})}{\epsilon} \quad (2) -$$ - -## Algorithm Steps - -### Matrix-Free Jv Product Setup -1. MOOSE sets up a `MatShell` for the Jacobian. -2. The `MatShell` is configured with a custom matrix-vector product routine, `mooseMatMult_NonEigen` (or `mooseMatMult_Eigen` for eigenvalue problems). -3. When PETSc needs to compute a Jacobian-vector product, it calls this registered routine. -4. Inside `mooseMatMult_NonEigen`, MOOSE's residual evaluation function (`evaluateResidual`) is called with the perturbed vector `x` to compute $R(u+\epsilon v)$. - -## Parameters -* `solve_type`: Controls the nonlinear solver method. - * `PJFNK`: Preconditioned Jacobian-Free Newton Krylov (default). - * `JFNK`: Jacobian-Free Newton Krylov (no preconditioning). - * `NEWTON`: Full Newton solve using an assembled Jacobian. - * `FD`: Jacobian assembled via finite differencing. - * `LINEAR`: Solves a linear problem. -* `matrix_free`: Boolean parameter to enable matrix-free operator formation. -* `precond_matrix_free`: Boolean parameter to enable matrix-free preconditioner formation. -* `mffd_type`: Specifies the finite differencing type for Jacobian-free solves. - * `wp`: Walker and Pernice (default). - * `ds`: Default PETSc finite difference. - -## Relationships - -` ` `mermaid -graph TD - A[Executioner] --> B{solve_type = JFNK/PJFNK}; - B -- "Sets up SNES" --> C[PETSc SNES]; - C -- "Calls SNESSetJacobian" --> D[MOOSE's Jacobian Callback]; - D -- "If matrix-free" --> E[MatShell]; - E -- "Sets MATOP_MULT to mooseMatMult_NonEigen" --> F[mooseMatMult_NonEigen]; - F -- "Calls evaluateResidual" --> G[MOOSE Residual Assembly]; - B -- "If PJFNK" --> H[Preconditioner Matrix Assembly]; - H -- "Uses computeQpJacobian/computeQpOffDiagJacobian" --> G; -` ` ` - -## Code Snippets - -### Setting up MatShell for Matrix-Free Jv Product -` ` `cpp -void -setOperationsForShellMat(EigenProblem & eigen_problem, Mat mat, bool eigen) -{ - LibmeshPetscCallA(eigen_problem.comm().get(), MatShellSetContext(mat, &eigen_problem)); - LibmeshPetscCallA(eigen_problem.comm().get(), - MatShellSetOperation(mat, - MATOP_MULT, - eigen ? (void (*)(void))mooseMatMult_Eigen - : (void (*)(void))mooseMatMult_NonEigen)); -} -` ` ` - -### `mooseMatMult_NonEigen` for Residual Evaluation -` ` `cpp -PetscErrorCode -mooseMatMult_NonEigen(Mat mat, Vec x, Vec r) -{ - PetscFunctionBegin; - void * ctx = nullptr; - LibmeshPetscCallQ(MatShellGetContext(mat, &ctx)); - - if (!ctx) - mooseError("No context is set for shell matrix "); - - EigenProblem * eigen_problem = static_cast(ctx); - NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem(); - - evaluateResidual(*eigen_problem, x, r, eigen_nl.nonEigenVectorTag()); - - PetscFunctionReturn(PETSC_SUCCESS); -} -` ` ` - -## Detailed Answers to Questions - -### 1. The matrix-free Jv product: how does MOOSE register a `MatShell` with PETSc for the Jacobian-free path? -MOOSE registers a `MatShell` with PETSc by calling `MatShellSetOperation` to associate a custom matrix-vector product function with the `MatShell` object. For non-eigenvalue problems, this function is `mooseMatMult_NonEigen`. The `mooseMatMult_NonEigen` function then retrieves the `EigenProblem` context and calls `evaluateResidual` to compute the residual, which is used in the finite-difference approximation of the Jacobian-vector product. - -### 2. `SNESSetJacobian` — does MOOSE provide both a matrix-free operator (shell) and a separate preconditioner matrix? -Yes, MOOSE can provide both a matrix-free operator (shell) and a separate preconditioner matrix. When `solve_type = PJFNK`, the Jacobian used by the Krylov solver is matrix-free, while a separate preconditioner matrix is assembled. The `mooseSlepcEigenFormJacobianA` function demonstrates this by checking if the Jacobian (`jac`) is `MATSHELL` or `MATMFFD` and if the preconditioner (`pc`) is also `MATSHELL`. If the preconditioner is not a shell, it will be assembled. - -### 3. The finite-difference parameter ε in J·v ≈ [R(u+εv) - R(u)]/ε — how is it chosen? `MATMFFD_DS` vs `MATMFFD_WP`? -The finite-difference parameter $\epsilon$ is chosen automatically by PETSc. The choice of the finite differencing type is controlled by the `mffd_type` parameter in MOOSE, which can be set to `wp` (Walker and Pernice, default) or `ds` (default PETSc finite difference). The PETSc option `-mat_mffd_err` controls $\epsilon$, not `-snes_mf_err`, unless `-snes_mf_version` is set to 2. - -### 4. When `solve_type = JFNK`: the preconditioner matrix is assembled (via SMP/FDP) but the actual Jacobian used by GMRES is matrix-free — confirm this architecture? -This statement is partially correct. When `solve_type = PJFNK`, the preconditioner matrix is assembled, and the actual Jacobian used by GMRES is matrix-free. However, when `solve_type = JFNK`, there is *no* preconditioning during the Krylov solve, and no Jacobian (or preconditioner) matrix is assembled. The architecture for PJFNK involves a matrix-free Jacobian-vector product and an assembled preconditioner. - -### 5. Can MOOSE do fully matrix-free (no preconditioner assembly at all)? When would this be useful? -Yes, MOOSE can do fully matrix-free by setting `solve_type = JFNK`. In this mode, no Jacobian or preconditioner matrix is assembled. This can be useful when memory is extremely constrained, or when the Jacobian is very difficult or expensive to assemble explicitly. However, JFNK often performs poorly without preconditioning, leading to slow convergence or divergence. - -### 6. How does the `-snes_mf` vs `-snes_mf_operator` PETSc flag map to MOOSE's behavior? -The PETSc flags `-snes_mf` and `-snes_mf_operator` are related to how PETSc handles matrix-free Jacobian approximations. -* `-snes_mf`: This flag tells PETSc to use a matrix-free Jacobian for the nonlinear solver. It implies that the Jacobian-vector product will be approximated using finite differences. -* `-snes_mf_operator`: This flag is used when you want to provide a matrix-free operator for the Jacobian but still use an explicitly assembled matrix for the preconditioner. This aligns with MOOSE's `PJFNK` behavior where the Jacobian is matrix-free but a preconditioner is assembled. - -MOOSE's `solve_type` parameter implicitly sets these PETSc options. For example, `PJFNK` would likely enable `-snes_mf_operator` (or similar configuration - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - - -## GPU acceleration and PETSc GPU backends in MOOSE - -MOOSE supports GPU-accelerated linear algebra primarily through its integration with PETSc and Kokkos. You can configure MOOSE to leverage CUDA or HIP backends for PETSc, and it also provides a Kokkos-MOOSE framework for GPU-accelerated element assembly and other operations. - -## PETSc GPU Backends -MOOSE supports PETSc with CUDA and HIP backends. The configuration for these is done when building PETSc, by including flags like `--with-cuda` or `--with-hip`. MOOSE also checks for `PETSC_HAVE_KOKKOS`, `PETSC_HAVE_CUDA`, and `PETSC_HAVE_HIP` during its own configuration. - -## `VecType` and `MatType` for GPU -MOOSE can utilize PETSc's GPU-specific `VecType` and `MatType` through its `libMesh` dependency. When PETSc is built with CUDA or HIP support, `libMesh` will use the appropriate GPU-enabled vector and matrix types (e.g., `VECCUDA`, `MATAIJCUSPARSE`). The `Moose::Kokkos::Matrix` class specifically handles `libMesh::PetscMatrix` objects and can create device-side storage for matrix values if Kokkos GPU capabilities are enabled. - -## Changes Needed in MOOSE to Run on GPU -Running MOOSE on GPU is not entirely transparent and requires specific configurations and code modifications for GPU-accelerated components. -1. **PETSc Configuration**: You need to build PETSc with GPU support (e.g., `--with-cuda`). -2. **MOOSE Configuration**: MOOSE itself needs to be configured with `--with-kokkos` to enable Kokkos-MOOSE capabilities. -3. **Code Modification for Kokkos-MOOSE**: For MOOSE objects to run on GPU using Kokkos, they need to be specifically written or adapted for the Kokkos-MOOSE framework. This involves using `KOKKOS_FUNCTION` for GPU-callable functions, using `Moose::Kokkos::Array` and other Kokkos-specific data structures for device memory, and implementing static polymorphism via CRTP instead of virtual functions. - -## Matrix-Free GPU Operations -The documentation indicates that `MFEMProblem` allows problem assembly and solution on GPU architectures, which implies that matrix-free operations like the JFNK Jv product could potentially run on the GPU if the residual evaluations are implemented for the device. However, explicit details on JFNK Jv product running on GPU are not provided in the given context. - -## Element Assembly on GPU -Yes, there is active work on GPU-accelerated element assembly in MOOSE via Kokkos. The Kokkos-MOOSE framework provides GPU versions of `Kernels`, `NodalKernels`, `BCs`, `Materials`, `AuxKernels`, and `Functions`. These Kokkos objects are designed to resemble their CPU counterparts but require specific GPU programming practices, such as using `KOKKOS_FUNCTION` and `Moose::Kokkos::Array`. - -## libMesh's Role -`libMesh` acts as an abstraction layer for the linear algebra backend, including PETSc. MOOSE interacts with PETSc primarily through `libMesh`. When PETSc is configured with GPU support, `libMesh` will automatically use the GPU-enabled PETSc functionalities. However, for element assembly and other MOOSE-specific operations to run on the GPU, MOOSE also provides its own Kokkos-based framework (`Kokkos-MOOSE`) which requires direct interaction with Kokkos programming paradigms. - -## Current Status -Currently, Kokkos-MOOSE is available for preliminary testing with NVIDIA GPUs. It supports GPU versions of `Kernels`, `NodalKernels`, `BCs`, `Materials`, `AuxKernels`, and `Functions`. Support for AMD and Intel GPUs is planned for the future. Some limitations exist, such as the lack of support for coupling with scalar variables and automatic differentiation in Kokkos-MOOSE kernels, and boundary-restricted elemental `AuxKernels`. - -## Performance -The provided context does not explicitly state for what problem sizes GPU acceleration becomes beneficial in MOOSE. However, general GPU programming principles suggest that GPUs are most effective for problems with high parallelism and large data sets, where the overhead of data transfer to and from the device is amortized by the computational speedup. - -## Configuration Flags and PETSc Options -### MOOSE Configuration Flags -* `--with-kokkos`: Enables Kokkos-MOOSE capabilities. - -### PETSc Configuration Flags -When building PETSc, you can use the following options: -* `--with-cuda`: Enables CUDA support. -* `--with-hip`: Enables HIP support. -* `--with-cuda-arch=[arch]`: Specifies the CUDA GPU architecture (e.g., `80` for `sm_80`). -* `--with-hip-arch=[arch]`: Specifies the HIP GPU architecture (e.g., `gfx908`). - -## MOOSE-specific GPU Classes or Interfaces -### Classes & Methods -* `Moose::Kokkos::Array`: A template class for multi-dimensional arrays designed for GPU access, supporting creation on host, device, or both, and explicit data synchronization. -* `Moose::Kokkos::JaggedArray`: A data container for jagged arrays on GPU. -* `Moose::Kokkos::Map`: A hash map implementation for GPU, using FNV-1a hash algorithm. -* `Moose::Kokkos::ReferenceWrapper`: A template class to hold a reference to a CPU variable and provide an up-to-date value on GPU, synchronizing via the copy constructor. -* `Moose::Kokkos::Scalar`: Derived from `Moose::Kokkos::ReferenceWrapper`, providing arithmetic operators for stored values. -* `Moose::Kokkos::Matrix::create(libMesh::SparseMatrix & matrix, const System & system)`: Creates a Kokkos-managed matrix from a `libMesh::PetscMatrix`, allocating device memory for values if GPU is enabled. -* `Moose::Kokkos::Kernel`: Base class for GPU-accelerated kernels, requiring `KOKKOS_FUNCTION` for hook methods like `computeQpResidual()`. - -### Code Snippets -**Example of `Moose::Kokkos::Array` wrapping a PETSc vector:** -` ` `cpp -PetscScalar * petsc_ptr; -PetscInt petsc_size; -VecGetArray(petsc_vector, &petsc_ptr); -VecGetLocalSize(petsc_vector, &petsc_size); - -Array vector; - -vector.createDevice(petsc_size); -vector.aliasHost(petsc_ptr); -vector.copyToDevice(); -` ` ` - -**Example of `KOKKOS_FUNCTION` usage in a Kokkos Kernel:** -` ` `cpp -KOKKOS_FUNCTION Real -KokkosDiffusion::computeQpResidual(const unsigned int i, - const unsigned int qp, - AssemblyDatum & datum) const -{ - return _grad_u(datum, qp) * _grad_test(datum, i, qp); -} -` ` ` - -## Notes -The `MFEMProblem` in MOOSE also offers GPU acceleration through the MFEM library, which can leverage CUDA or HIP. This is a separate but related path to GPU acceleration compared to the Kokkos-MOOSE framework. - -Wiki pages you might want to explore: -- [Executioner and Time Integration (idaholab/moose)](https://deepwiki.com/idaholab/moose#3.2) - - -## Custom PETSc solver configurations and fieldsplit - -MOOSE extensively leverages PETSc for advanced solver configurations, particularly through its `FieldSplitPreconditioner` and `Split` objects, allowing for detailed control over block preconditioning, Schur complement methods, and custom solver types. It also provides mechanisms for PETSc monitoring and integration with external packages. - -## PETScFieldSplit -MOOSE sets up PETSc's `PCFIELDSPLIT` for block preconditioning using the `FieldSplitPreconditioner` class . This preconditioner allows for custom preconditioning for each nonlinear variable in the numerical system . The `FieldSplitPreconditioner` is initialized with a `topsplit` parameter, which defines the entry point for the splitting hierarchy . - -The `FieldSplitPreconditioner` constructs a `CouplingMatrix` to define how variables couple . By default, `full=true` creates a fully coupled Jacobian matrix, but users can specify `off_diag_row` and `off_diag_column` to define custom couplings . The `_nl.useFieldSplitPreconditioner(this)` call registers the preconditioner with the nonlinear system . - -### MOOSE Input Syntax -An example of setting up a `FieldSplitPreconditioner` for variables 'u' and 'v' with an additive splitting type: -` ` `ini -[Preconditioning] - [FSP] - type = FSP - topsplit = 'uv' - [uv] - splitting = 'u v' - splitting_type = additive - [] - [u] - symbol_names = 'u' - petsc_options_iname = '-pc_type -ksp_type' - petsc_options_value = ' hypre preonly' - [] - [v] - symbol_names = 'v' - petsc_options_iname = '-pc_type -ksp_type' - petsc_options_value = ' hypre preonly' - [] - [] -` ` ` - -## Schur Complement Preconditioners -MOOSE can use PETSc's Schur factorization for saddle-point problems. The `Split` object, which is used within `FieldSplitPreconditioner`, has parameters to control Schur complement behavior . - -**Parameters:** -* `splitting_type = schur`: Specifies that the splitting should use Schur factorization . -* `schur_type = "diag" | "upper" | "lower" | "full"`: Controls the type of Schur complement factorization . -* `schur_pre = "S" | "Sp" | "A11"`: Determines which preconditioning matrix to use with $S = D - CA^{-1}B$ . - -The `NavierStokesProblem` specifically demonstrates the use of Schur complement preconditioning, including the Least Squares Commutator (LSC) preconditioner . It can configure the Schur complement preconditioner to be a pressure mass matrix or an LSC preconditioner . - -## Custom KSP/PC Types -Users can specify nested solver configurations through the `Split` objects within the `[Preconditioning]` block . Each sub-split can have its own `petsc_options_iname` and `petsc_options_value` parameters, allowing for fine-grained control over the `KSP` and `PC` types for different blocks . For example, you can set `hypre` for `pc_type` and `preonly` for `ksp_type` for a specific variable's subsolver . - -## PETSc DM Integration -MOOSE uses a custom `DMMoose` object for structured solver information, particularly in the context of `FieldSplitPreconditioner` . The `FieldSplitPreconditioner::createMooseDM` method creates and sets up this `DM` object, associating it with the nonlinear system and its `DofMap` . This `DM` object is then set on the `SNES` solver . - -## Matrix-Free Preconditioners -MOOSE supports matrix-free Jacobian-vector products, especially with the `PJFNK` (Preconditioned Jacobian-Free Newton Krylov) solve type . While the documentation mentions `PCShell` in the context of custom preconditioners, the provided snippets do not explicitly show how users can provide a custom `PCShell` through MOOSE input files. However, the `PCApply_MoosePC` function in `SlepcSupport.C` suggests a mechanism for applying a MOOSE-defined preconditioner within PETSc, which could potentially be extended to a `PCShell` . - -## PETSc Monitoring -PETSc monitoring options like `-ksp_monitor`, `-snes_monitor`, and `-log_view` can be enabled through MOOSE input files using the `petsc_options` parameter in the `Executioner` block or within `[Preconditioning]` blocks . - -**Parameters:** -* `petsc_options = '-ksp_monitor -snes_monitor -log_view'`: Directly sets these PETSc flags . -* `petsc_options_iname = '-ksp_monitor'` and `petsc_options_value = ''`: Can also be used for flags . - -These options are processed by `Moose::PetscSupport::storePetscOptions` , which adds them to a `PetscOptions` object that is then used to set PETSc options . - -## External Packages through PETSc -MOOSE can configure external packages like MUMPS, SuperLU, and HYPRE (ML is not explicitly mentioned in the provided context but HYPRE is) through PETSc options in the input file . - -**Parameters:** -* `petsc_options_iname = '-pc_type -pc_hypre_type'` -* `petsc_options_value = 'hypre boomeramg'` - -For SuperLU, specific options like `-mat_superlu_dist_replacetinypivot` can be set . These are passed via the `petsc_options_iname` and `petsc_options_value` parameters, which are then processed by `Moose::PetscSupport::storePetscOptions` . - -## Classes & Methods -* `FieldSplitPreconditioner::validParams()`: Registers valid input parameters for the `FieldSplitPreconditioner` . -* `FieldSplitPreconditioner::FieldSplitPreconditioner()`: Constructor that initializes the preconditioner, sets up the `CouplingMatrix`, and registers itself with the nonlinear system . -* `FieldSplitPreconditioner::createMooseDM()`: Creates and configures the `DMMoose` object for the field split . -* `Split::validParams()`: Registers valid input parameters for a `Split` object, including options for splitting type, Schur type, and PETSc options . -* `Split::setup()`: Configures the PETSc options for a given split, including setting the splitting type, Schur type, and recursively setting up sub-splits . -* `Moose::PetscSupport::storePetscOptions()`: Processes and stores PETSc options from MOOSE input parameters . -* `NavierStokesProblem::setupLSCMatrices()`: Sets up the Least Squares Commutator (LSC) preconditioner for the Schur complement . -* `PCApply_MoosePC()`: A PETSc callback function that applies a MOOSE-defined preconditioner . - -## Parameters -* `topsplit = 'string'`: (Type: `std::string`, Required) The name of the top-level split, which defines the entry point for the splitting hierarchy . -* `full = true | false`: (Type: `bool`, Default: `true`) If `true`, a full coupling Jacobian matrix is constructed. If `false`, `off_diag_row` and `off_diag_column` must be specified . -* `off_diag_row = 'vector'`: (Type: `std::vector`) Specifies rows for off-diagonal coupling . -* `off_diag_column = 'vector'`: (Type: `std::vector`) Specifies columns for off-diagonal coupling . -* `splitting = 'vector'`: (Type: `std::vector`) The names of the sub-splits (subsystems) in the decomposition of this split . -* `splitting_type = "additive" | "multiplicative" | "symmetric_multiplicative" | "schur"`: (Type: `MooseEnum`, Default: `additive`) The type of split decomposition . -* `schur_type = "diag" | "upper" | "lower" | "full"`: (Type: `MooseEnum`, Default: `full`) Type of Schur complement factorization . -* `schur_pre = "S" | "Sp" | "A11"`: (Type: `MooseEnum`, Default: `S`) Type of Schur complement preconditioner matrix . -* `petsc_options = 'MultiMooseEnum'`: (Type: `MultiMooseEnum`) Singleton PETSc options (flags) . -* `petsc_options_iname = 'MultiMooseEnum'`: (Type: `MultiMooseEnum`) Names of PETSc name/value pairs . -* `petsc_options_value = 'vector'`: (Type: `std::vector`) - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-linalg.md b/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-linalg.md deleted file mode 100644 index 65234b7..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-linalg.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -id: moose-petsc-linalg -title: MOOSE MOOSE-PETSc linear algebra interface -domain: solver -subdomain: procedural -tags: -- PETSc -- linear-algebra -- sparse-matrix -- preallocation -- libMesh-wrapper -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-petsc-interface - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-petsc-interface -- to: tgs-dom-linear-solvers - type: implements - weight: 0.7 - note: MOOSE-PETSc linear algebra plumbing ---- - -# MOOSE MOOSE-PETSc linear algebra interface - -MOOSE leverages `libMesh` as an intermediary layer to interface with PETSc for linear algebra operations. `libMesh::PetscMatrix` and `libMesh::PetscVector` wrap the underlying PETSc data structures, and MOOSE's `NonlinearSystem` registers its residual and Jacobian computation routines with PETSc's SNES solver. - -## MOOSE to PETSc Interface Overview - -MOOSE's problem-solving architecture, centered around `FEProblemBase` and `NonlinearSystemBase`, orchestrates the definition, assembly, and solution of systems of equations . `libMesh` provides the finite element infrastructure and acts as a bridge to PETSc . - -` ` `mermaid -graph TD - subgraph "MOOSE" - A["FEProblemBase"] - B["NonlinearSystem"] - C["Assembly"] - end - - subgraph "libMesh" - D["NonlinearImplicitSystem"] - E["PetscMatrix"] - F["PetscVector"] - G["DofMap"] - end - - subgraph "PETSc" - H["SNES"] - I["Mat"] - J["Vec"] - end - - A --> B - B --> C - B --> D - D --> E - D --> F - D --> G - E --> I - F --> J - D -- "Registers callbacks" --> H - H -- "Calls back to" --> D -` ` ` - -## 1. Assembled Matrices and PETSc Mat Types - -MOOSE passes assembled matrices to PETSc through `libMesh::PetscMatrix` objects . `libMesh::PetscMatrix` wraps a PETSc `Mat` object . The specific `Mat` type (e.g., `MATAIJ`, `MATBAIJ`) is typically determined by PETSc's defaults or user-specified options . MOOSE allows users to specify the matrix type via the `petsc_options_iname` and `petsc_options_value` parameters, for example, `-mat_type aij` . - -## 2. `NonlinearSystem` → PETSc SNES Connection - -The `NonlinearSystem` in MOOSE registers its residual and Jacobian functions with PETSc's SNES solver through `libMesh::PetscNonlinearSolver` . - -### Residual Function Registration - -The residual function is registered with SNES via `DMSNESSetFunction` , which points to `SNESFunction_DMMoose` . `SNESFunction_DMMoose` then calls `DMMooseFunction` , which retrieves the MOOSE `NonlinearSystemBase` and invokes its residual computation routines . - -### Jacobian Function Registration - -Similarly, the Jacobian function is registered using `DMSNESSetJacobian` , which points to `SNESJacobian_DMMoose` . `SNESJacobian_DMMoose` calls `DMMooseJacobian` , which in turn obtains the `NonlinearSystemBase` and calls its Jacobian computation methods . For finite-differenced preconditioners, `SNESSetJacobian` can also be used with `SNESComputeJacobianDefault` or `MatFDColoringSetFunction` . - -## 3. `libMesh::PetscMatrix` and `libMesh::PetscVector` - -`libMesh::PetscMatrix` and `libMesh::PetscVector` are wrapper classes provided by `libMesh` that encapsulate PETSc's `Mat` and `Vec` data structures, respectively . They provide a `libMesh` interface while managing the underlying PETSc objects. For example, `PetscMatrix::mat()` returns the raw PETSc `Mat` pointer . - -## 4. Sparse Matrix Assembly - -MOOSE's element-level contributions (e.g., `_local_ke` from kernels) are assembled into the global PETSc `Mat` through `libMesh`'s assembly routines. These routines ultimately make calls to PETSc's `MatSetValues()` or similar functions to insert local matrix entries into the global sparse matrix . The `Assembly` class in MOOSE is responsible for gathering these contributions from various physics components . - -## 5. Matrix Preallocation - -MOOSE determines the sparsity pattern and preallocates the PETSc matrix during the setup phase. The `libMesh::DofMap` plays a crucial role in defining the global degrees of freedom and their connectivity, which is used to build the sparsity pattern . `MatCreate` and `MatSetSizes` are called, followed by `MatSetType` to specify the matrix type . For certain matrix types, `MatSetPreallocationCOO` can be used for efficient preallocation . - -## 6. Block Structure for Multi-Variable Problems - -For multi-variable problems, MOOSE primarily uses a monolithic matrix approach where all variables are part of a single system . However, it can leverage PETSc's block preconditioning capabilities, such as field-split preconditioners, to improve convergence . The `PetscDMMoose` utility provides functions like `DMMooseSetSplitNames` and `DMMooseSetSplitVars` to define these field splits for PETSc's `DM` objects . - -## 7. Exposing PETSc Options to the User - -MOOSE exposes PETSc options to the user through input file parameters: `petsc_options`, `petsc_options_iname`, and `petsc_options_value` . - -* `petsc_options`: Used for single-flag PETSc options (e.g., `-snes_mf`) . -* `petsc_options_iname`: Specifies the names of PETSc key-value pairs (e.g., `-pc_type`) . -* `petsc_options_value`: Provides the corresponding values for the `petsc_options_iname` parameters (e.g., `hypre`) . - -These parameters allow for raw PETSc command-line pass-through, enabling users to fine-tune PETSc's solvers and preconditioners . The `PetscSupport::addPetscFlagsToPetscOptions` and `PetscSupport::addPetscPairsToPetscOptions` functions process these input parameters and set the options within PETSc . - -## Classes & Methods - -* `NonlinearSystem::compute_jacobian()`: A static function called by `libMesh` to compute the Jacobian matrix . -* `NonlinearSystem::setupColoringFiniteDifferencedPreconditioner()`: Configures PETSc for finite-differenced Jacobian computation using coloring . -* `DMMooseFunction()`: A static PETSc callback function that computes the residual for a `DM` object . -* `SNESFunction_DMMoose()`: The PETSc SNES callback for residual computation, which calls `DMMooseFunction` . -* `DMMooseJacobian()`: A static PETSc callback function that computes the Jacobian matrix for a `DM` object . -* `SNESJacobian_DMMoose()`: The PETSc SNES callback for Jacobian computation, which calls `DMMooseJacobian` . -* `DMCreateMoose()`: Creates a MOOSE-specific PETSc `DM` object . -* `DMCreateMatrix_Moose()`: Creates a PETSc `Mat` object associated with a MOOSE `DM` . -* `PetscSupport::petscSetOptions()`: Sets PETSc options from MOOSE's `PetscOptions` object . -* `PetscSupport::addPetscFlagsToPetscOptions()`: Populates `PetscOptions` with single-flag PETSc options from input parameters . -* `PetscSupport::addPetscPairsToPetscOptions()`: Populates `PetscOptions` with key-value pair PETSc options from input parameters . - -## Parameters - -* `solve_type = PJFNK | JFNK | NEWTON | FD | LINEAR`: Controls the nonlinear solver method . -* `mffd_type = wp | ds`: Specifies the finite differencing type for Jacobian-free solves . -* `petsc_options = `: Singleton PETSc options (e.g., `-snes_ksp_ew`) . -* `petsc_options_iname = `: Names of PETSc name/value pairs (e.g., `-pc_type`) . -* `petsc_options_value = `: Values corresponding to `petsc_options_iname` (e.g., `hypre`) . - -## MOOSE Input Syntax - -` ` `ini -[Executioner] - type = Steady - solve_type = PJFNK - petsc_options_iname = '-pc_type -pc_hypre_type' - petsc_options_value = 'hypre boomeramg' -[] -` ` ` - - -## Notes - -The interaction between MOOSE and PETSc is primarily mediated by `libMesh`. `libMesh` provides the `PetscMatrix` and `PetscVector` wrappers, and its `NonlinearImplicitSystem` registers the necessary callbacks with PETSc's SNES solver. The `PetscDMMoose` utility plays a significant role in setting up the PETSc `DM` object and connecting it to MOOSE's `NonlinearSystemBase` for residual and Jacobian evaluations. Users have extensive control over PETSc's behavior through input file parameters, allowing for flexible solver and preconditioner configurations. - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-matshell.md b/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-matshell.md deleted file mode 100644 index 8635215..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-petsc-matshell.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -id: moose-petsc-matshell -title: MOOSE Matrix-free operations and JFNK implementation details -domain: solver -subdomain: procedural -tags: -- matrix-free -- MatShell -- JFNK -- finite-difference-Jv -- SNES -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-petsc-interface - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-petsc-interface -- to: cm-solver-matrixfree - type: implements - weight: 0.9 - note: MatShell for matrix-free JFNK Jacobian-vector product ---- - -# MOOSE Matrix-free operations and JFNK implementation details - -MOOSE implements matrix-free Jacobian-vector products for JFNK by leveraging PETSc's `MatShell` and `MatMFFD` functionalities. It registers a custom matrix-vector product routine with PETSc, which internally calls MOOSE's residual evaluation function. For preconditioning, MOOSE can either assemble a separate matrix or operate in a fully matrix-free mode. - -## Classes & Methods -* `Moose::SlepcSupport::setOperationsForShellMat(EigenProblem & eigen_problem, Mat mat, bool eigen)`: Sets the matrix-vector product operation for a PETSc `MatShell` based on whether it's for an eigen problem or not. -* `Moose::SlepcSupport::mooseMatMult_NonEigen(Mat mat, Vec x, Vec r)`: The callback function for `MATOP_MULT` when the `MatShell` represents the non-eigen part of the Jacobian. It evaluates the residual. -* `NonlinearSystem::setupFiniteDifferencedPreconditioner()`: Configures the finite-differenced preconditioner, which can be either "coloring" or "standard". -* `SNESSetJacobian()`: A PETSc function used to set the Jacobian evaluation function for the nonlinear solver. - -## Equations -The Jacobian-vector product for JFNK is approximated using a finite-difference formula: -$$ -\mathbf{J}(\mathbf{u}^{i-1}) \mathbf{y} \approx \frac{\mathbf{R}(\mathbf{u}^{i-1} + \epsilon \mathbf{y}) - \mathbf{R}(\mathbf{u}^{i-1})}{\epsilon} \quad (1) -$$ -For preconditioned JFNK (PJFNK), the action of the preconditioned Jacobian is approximated as: -$$ -\mathbf{J} \mathbf{P}^{-1}\mathbf{v} \approx \frac{\mathbf{R}(\mathbf{u} + \epsilon \mathbf{P}^{-1}\mathbf{v}) - \mathbf{R}(\mathbf{u})}{\epsilon} \quad (2) -$$ - -## Algorithm Steps - -### Matrix-Free Jv Product Setup -1. MOOSE sets up a `MatShell` for the Jacobian. -2. The `MatShell` is configured with a custom matrix-vector product routine, `mooseMatMult_NonEigen` (or `mooseMatMult_Eigen` for eigenvalue problems). -3. When PETSc needs to compute a Jacobian-vector product, it calls this registered routine. -4. Inside `mooseMatMult_NonEigen`, MOOSE's residual evaluation function (`evaluateResidual`) is called with the perturbed vector `x` to compute $R(u+\epsilon v)$. - -## Parameters -* `solve_type`: Controls the nonlinear solver method. - * `PJFNK`: Preconditioned Jacobian-Free Newton Krylov (default). - * `JFNK`: Jacobian-Free Newton Krylov (no preconditioning). - * `NEWTON`: Full Newton solve using an assembled Jacobian. - * `FD`: Jacobian assembled via finite differencing. - * `LINEAR`: Solves a linear problem. -* `matrix_free`: Boolean parameter to enable matrix-free operator formation. -* `precond_matrix_free`: Boolean parameter to enable matrix-free preconditioner formation. -* `mffd_type`: Specifies the finite differencing type for Jacobian-free solves. - * `wp`: Walker and Pernice (default). - * `ds`: Default PETSc finite difference. - -## Relationships - -` ` `mermaid -graph TD - A[Executioner] --> B{solve_type = JFNK/PJFNK}; - B -- "Sets up SNES" --> C[PETSc SNES]; - C -- "Calls SNESSetJacobian" --> D[MOOSE's Jacobian Callback]; - D -- "If matrix-free" --> E[MatShell]; - E -- "Sets MATOP_MULT to mooseMatMult_NonEigen" --> F[mooseMatMult_NonEigen]; - F -- "Calls evaluateResidual" --> G[MOOSE Residual Assembly]; - B -- "If PJFNK" --> H[Preconditioner Matrix Assembly]; - H -- "Uses computeQpJacobian/computeQpOffDiagJacobian" --> G; -` ` ` - -## Code Snippets - -### Setting up MatShell for Matrix-Free Jv Product -` ` `cpp -void -setOperationsForShellMat(EigenProblem & eigen_problem, Mat mat, bool eigen) -{ - LibmeshPetscCallA(eigen_problem.comm().get(), MatShellSetContext(mat, &eigen_problem)); - LibmeshPetscCallA(eigen_problem.comm().get(), - MatShellSetOperation(mat, - MATOP_MULT, - eigen ? (void (*)(void))mooseMatMult_Eigen - : (void (*)(void))mooseMatMult_NonEigen)); -} -` ` ` - -### `mooseMatMult_NonEigen` for Residual Evaluation -` ` `cpp -PetscErrorCode -mooseMatMult_NonEigen(Mat mat, Vec x, Vec r) -{ - PetscFunctionBegin; - void * ctx = nullptr; - LibmeshPetscCallQ(MatShellGetContext(mat, &ctx)); - - if (!ctx) - mooseError("No context is set for shell matrix "); - - EigenProblem * eigen_problem = static_cast(ctx); - NonlinearEigenSystem & eigen_nl = eigen_problem->getCurrentNonlinearEigenSystem(); - - evaluateResidual(*eigen_problem, x, r, eigen_nl.nonEigenVectorTag()); - - PetscFunctionReturn(PETSC_SUCCESS); -} -` ` ` - -## Detailed Answers to Questions - -### 1. The matrix-free Jv product: how does MOOSE register a `MatShell` with PETSc for the Jacobian-free path? -MOOSE registers a `MatShell` with PETSc by calling `MatShellSetOperation` to associate a custom matrix-vector product function with the `MatShell` object. For non-eigenvalue problems, this function is `mooseMatMult_NonEigen`. The `mooseMatMult_NonEigen` function then retrieves the `EigenProblem` context and calls `evaluateResidual` to compute the residual, which is used in the finite-difference approximation of the Jacobian-vector product. - -### 2. `SNESSetJacobian` — does MOOSE provide both a matrix-free operator (shell) and a separate preconditioner matrix? -Yes, MOOSE can provide both a matrix-free operator (shell) and a separate preconditioner matrix. When `solve_type = PJFNK`, the Jacobian used by the Krylov solver is matrix-free, while a separate preconditioner matrix is assembled. The `mooseSlepcEigenFormJacobianA` function demonstrates this by checking if the Jacobian (`jac`) is `MATSHELL` or `MATMFFD` and if the preconditioner (`pc`) is also `MATSHELL`. If the preconditioner is not a shell, it will be assembled. - -### 3. The finite-difference parameter ε in J·v ≈ [R(u+εv) - R(u)]/ε — how is it chosen? `MATMFFD_DS` vs `MATMFFD_WP`? -The finite-difference parameter $\epsilon$ is chosen automatically by PETSc. The choice of the finite differencing type is controlled by the `mffd_type` parameter in MOOSE, which can be set to `wp` (Walker and Pernice, default) or `ds` (default PETSc finite difference). The PETSc option `-mat_mffd_err` controls $\epsilon$, not `-snes_mf_err`, unless `-snes_mf_version` is set to 2. - -### 4. When `solve_type = JFNK`: the preconditioner matrix is assembled (via SMP/FDP) but the actual Jacobian used by GMRES is matrix-free — confirm this architecture? -This statement is partially correct. When `solve_type = PJFNK`, the preconditioner matrix is assembled, and the actual Jacobian used by GMRES is matrix-free. However, when `solve_type = JFNK`, there is *no* preconditioning during the Krylov solve, and no Jacobian (or preconditioner) matrix is assembled. The architecture for PJFNK involves a matrix-free Jacobian-vector product and an assembled preconditioner. - -### 5. Can MOOSE do fully matrix-free (no preconditioner assembly at all)? When would this be useful? -Yes, MOOSE can do fully matrix-free by setting `solve_type = JFNK`. In this mode, no Jacobian or preconditioner matrix is assembled. This can be useful when memory is extremely constrained, or when the Jacobian is very difficult or expensive to assemble explicitly. However, JFNK often performs poorly without preconditioning, leading to slow convergence or divergence. - -### 6. How does the `-snes_mf` vs `-snes_mf_operator` PETSc flag map to MOOSE's behavior? -The PETSc flags `-snes_mf` and `-snes_mf_operator` are related to how PETSc handles matrix-free Jacobian approximations. -* `-snes_mf`: This flag tells PETSc to use a matrix-free Jacobian for the nonlinear solver. It implies that the Jacobian-vector product will be approximated using finite differences. -* `-snes_mf_operator`: This flag is used when you want to provide a matrix-free operator for the Jacobian but still use an explicitly assembled matrix for the preconditioner. This aligns with MOOSE's `PJFNK` behavior where the Jacobian is matrix-free but a preconditioner is assembled. - -MOOSE's `solve_type` parameter implicitly sets these PETSc options. For example, `PJFNK` would likely enable `-snes_mf_operator` (or similar configuration - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-constitutive-params.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-constitutive-params.md deleted file mode 100644 index 935c8ed..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-constitutive-params.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -id: moose-pf-constitutive-params -title: MOOSE Phase field parameters in constitutive models -domain: phase-field -subdomain: algorithmic -tags: -- composite-elasticity -- phase-dependent-moduli -- swelling-eigenstrain -- CTE-per-phase -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-phase-field-mechanics-coupling - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-phase-field-mechanics-coupling ---- - -# MOOSE Phase field parameters in constitutive models - -MOOSE integrates phase field variables into solid mechanics constitutive models primarily through material classes that allow for phase-dependent material properties and stress calculations. - -## Phase-dependent elastic moduli: $C(\eta) = h(\eta) \cdot C_{phase1} + (1-h(\eta)) \cdot C_{phase2}$ - -The `ComputeConcentrationDependentElasticityTensor` class is used to define an elasticity tensor that depends on a concentration field, which can represent a phase field variable . This class interpolates between two elasticity tensors, `_Cijkl0` and `_Cijkl1`, based on the value of a coupled concentration variable `_c` . - -### Classes & Methods: -* `ComputeConcentrationDependentElasticityTensor::validParams()`: Defines the input parameters for the concentration-dependent elasticity tensor, including two stiffness tensors (`C0_ijkl`, `C1_ijkl`) and a coupled concentration variable (`c`) . -* `ComputeConcentrationDependentElasticityTensor::computeQpElasticityTensor()`: Computes the elasticity tensor at a given quadrature point using a linear interpolation formula . - -### Equations: -The elasticity tensor $C$ is computed as: -$$ -C = C_{ijkl0} + (C_{ijkl1} - C_{ijkl0}) \cdot c \quad (1) -$$ -where $C_{ijkl0}$ is the stiffness tensor for zero concentration, $C_{ijkl1}$ is the stiffness tensor for concentration 1.0, and $c$ is the concentration variable . - -## `CompositeElasticityTensor` — how does it interpolate tensors between phases? - -The `CompositeElasticityTensor` class is used to combine multiple elasticity tensors with corresponding weights . While the provided snippets do not show its C++ implementation, an example input file demonstrates its usage where `tensors` are combined with `weights` . This allows for interpolation of elasticity tensors based on material properties that can be derived from phase field variables. - -## Creep/plasticity parameters that depend on phase - -MOOSE supports phase-dependent creep and plasticity parameters. The test suite for `CompositePowerLawCreepStressUpdate` indicates that the system provides phase-dependent power law creep that can handle different material properties for different phases . This includes scenarios with multiple plasticity rules for different phases . The input parameters for such creep models, like activation energy, coefficient, and n-exponent, are expected to have lengths equal to the number of switching functions (phases) . - -## Swelling eigenstrains: coupling species concentration c to volumetric strain - -The `ElasticEnergyMaterial` class is designed to handle elastic energy contributions and can fetch stress and elasticity tensor derivatives with respect to coupled variables . This framework allows for coupling species concentration `c` to volumetric strain by defining the elastic strain and elasticity tensor as functions of `c` and their derivatives. - -## Thermal expansion differences between phases: phase-dependent CTE - -While not explicitly shown in the provided snippets, the general approach for phase-dependent material properties in MOOSE, as demonstrated with elasticity tensors and creep parameters, would extend to thermal expansion coefficients. A material class similar to `ComputeConcentrationDependentElasticityTensor` could be implemented to interpolate CTE values based on a phase field variable. - -## How to ensure thermodynamic consistency when mixing phase field and mechanics? - -Thermodynamic consistency in coupled phase field and mechanics problems is ensured by defining a global free energy functional that includes contributions from both the local free energy density ($f_{loc}$), gradient energy density ($f_{gr}$), and additional energy sources like deformation energy ($E_d$) . The evolution equations for phase field variables (conserved and non-conserved) are derived from the functional derivatives of this global free energy . - -For two-phase models, the `DerivativeTwoPhaseMaterial` combines phase free energies into a global free energy using a switching function $h(\eta)$ . -$$ -F = (1-h(\eta)) F_a + h(\eta)F_b + Wg(\eta) \quad (2) -$$ -where $F_a$ and $F_b$ are the free energies of phase A and B, respectively, and $\eta$ is the order parameter. The `TwoPhaseStressMaterial` and `MultiPhaseStressMaterial` classes calculate global stress and its derivative with respect to strain by interpolating between phase-specific stresses and stiffnesses using a switching function `_h_eta` . This approach ensures that the mechanical response is consistent with the phase distribution. - -### Classes & Methods: -* `TwoPhaseStressMaterial::computeQpProperties()`: Computes the global stress and its Jacobian by linearly interpolating between the stresses and Jacobians of two phases using a switching function `_h_eta` . -* `ElasticEnergyMaterial`: A free energy material for elastic energy contributions, which can be coupled with other variables like concentration . - -### MOOSE Input Syntax: -For phase-dependent elastic moduli using `ComputeConcentrationDependentElasticityTensor`: -` ` `ini -[Materials] - [./elasticity_tensor] - type = ComputeConcentrationDependentElasticityTensor - block = '1' - C0_ijkl = '...' # Stiffness tensor for zero concentration phase - C1_ijkl = '...' # Stiffness tensor for concentration 1.0 phase - c = concentration_variable # Coupled concentration variable - [../] -[] -` ` ` - -For combining stresses from multiple phases using `TwoPhaseStressMaterial`: -` ` `ini -[Materials] - [./phase_A_stress] - type = SomeElasticStressMaterial - block = '1' - # ... parameters for phase A stress - [../] - [./phase_B_stress] - type = SomeElasticStressMaterial - block = '1' - # ... parameters for phase B stress - [../] - [./switching_function] - type = SwitchingFunctionMaterial - block = '1' - # ... parameters for h(eta) - [../] - [./global_stress] - type = TwoPhaseStressMaterial - block = '1' - h = switching_function # Material property providing h(eta) - base_A = phase_A_stress # Base name for Phase A strain/stress - base_B = phase_B_stress # Base name for Phase B strain/stress - [../] -[] -` ` ` - -## Notes -The provided context primarily focuses on elastic properties and general free energy formulations. Specific implementations for phase-dependent thermal expansion coefficients (CTE) were not directly found, but the framework suggests that similar material classes could be developed. The `ComputePolycrystalElasticityTensor` class also deals with evolving elasticity tensors coupled to grain growth phase field models, which is a related concept but not directly addressing the user's specific question about $C(\eta) = h(\eta) \cdot C_{phase1} + (1-h(\eta)) \cdot C_{phase2}$ . - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-constraints.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-constraints.md deleted file mode 100644 index 41fc4a9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-constraints.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -id: moose-pf-constraints -title: MOOSE Constraint enforcement and numerical stabilization -domain: phase-field -subdomain: algorithmic -tags: -- constraints -- lagrange-multiplier -- penalty -- mass-conservation -- nucleation -- interface-width -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-phase-field-numerics - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-phase-field-numerics ---- - -# MOOSE Constraint enforcement and numerical stabilization - -MOOSE employs various numerical techniques for phase field simulations, including specific approaches for nucleation events and time step adaptivity. The framework provides kernels for solving both Allen-Cahn and Cahn-Hilliard equations, allowing for different solution strategies. - -## Phase Field Nucleation -MOOSE handles nucleation events through a `DiscreteNucleation` system . This system artificially triggers and stabilizes nuclei formation by locally modifying the free energy density or directly changing an order parameter . - -### Classes & Methods -* `DiscreteNucleationInserter`: A user object that manages a global list of active nucleus positions . -* `DiscreteNucleationMap`: A user object that maintains a smooth density map for nuclei locations, obtained from a `DiscreteNucleationInserter` . -* `DiscreteNucleation`: A material that calculates a local free energy penalty based on the difference between concentration variables and their target concentrations . -* `DiscreteNucleationTimeStep`: A postprocessor that provides a time step limit for new nuclei, used with `IterationAdaptiveDT` . - -### Parameters -* `DiscreteNucleation::penalty`: `Real`, default `20.0`. Penalty factor for enforcing target concentrations . -* `DiscreteNucleation::penalty_mode`: `MooseEnum`, default `MATCH`. Determines if the target concentration is matched, or taken as a minimum or maximum . -* `DiscreteNucleationTimeStep::dt_max`: `Real`. Time step to cut back to at the start of a nucleation event . -* `DiscreteNucleationTimeStep::p2nucleus`: `Real`, range `(0, 1)`. Maximum probability for more than one nucleus to appear during a time step . - -### Free Energy Penalty Based Nucleation -The `DiscreteNucleation` material implements a harmonic form of a free energy penalty to bias the system's thermodynamics, driving the formation of nuclei . - -### Direct Order Parameter Modification -For non-conserved order parameters, direct modification can be achieved by applying a `DiscreteNucleationForce` and a `Reaction` kernel to a reserved order parameter . - -## Time Integration Schemes -MOOSE's `Transient` executioner allows for time-dependent simulations . The `scheme` parameter in the `Executioner` block determines the `TimeIntegrator` to use . While the documentation mentions Backward Euler as a default , it also supports other schemes like BDF2 . - -## Time Step Adaptivity -Time step adaptivity is supported through objects like `DiscreteNucleationTimeStep` and `IterationAdaptiveDT` . The `DiscreteNucleationTimeStep` postprocessor limits the time step based on two criteria: a user-defined `dt_max` at nucleus insertion and a nucleation rate-based limit to control the probability of multiple nucleation events within a single time step . - -### Equations -The probability of more than two nucleation events ($p_{2nuc}$) is calculated as: -$$ -p_{2nuc} = 1-(1+\lambda_{2nuc})e^{-\lambda_{2nuc}} \label{eq:p2nuc} \tag{1} -$$ -where $\lambda_{2nuc}$ is the total nucleation rate over the simulation cell . This equation is numerically inverted to obtain $\lambda_{2nuc}$ for a given $p_{2nuc}$ . - -## Mass Conservation for Cahn-Hilliard -The Cahn-Hilliard equation, which describes mass conservation, can be solved in two ways within MOOSE . -1. **Direct solution of the fourth-order equation**: This involves solving the equation directly . -2. **Split into two second-order equations**: This approach solves for concentration ($c_i$) and chemical potential ($\mu_i$) separately . This method is noted to improve solve convergence . - -### Equations -The residual for the direct solution of the Cahn-Hilliard equation is: -$$ -\boldsymbol{\mathcal{R}}_{c_i} = \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( \kappa_i \nabla^2 c_i, \nabla \cdot (M_i \nabla \psi_m ) \right) + \left( M_i \left( \nabla \frac{\partial f_{loc} }{\partial c_i} + \nabla \frac{\partial E_d}{\partial c_i} \right), \nabla \psi_m \right) \label{eq:ch_direct_residual} \tag{2} -$$ -For the split form, the two residual equations are: -$$ -\begin{aligned} - \boldsymbol{\mathcal{R}}_{\mu_i} &=& \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( M_i \nabla \mu_i, \nabla \psi_m \right) \\ - \boldsymbol{\mathcal{R}}_{c_i} &=& \left( \left( -\kappa_i \nabla^2 c_i + \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \mu_i \right), \psi_m \right) -\end{aligned} \label{eq:ch_split_residual} \tag{3} -$$ - -## Order Parameter Constraint $\Sigma\eta_i = 1$ -The provided context does not explicitly detail the numerical techniques used for enforcing the order parameter constraint $\Sigma\eta_i = 1$, such as penalty methods, Lagrange multipliers, or variable elimination. - -## Numerical Stabilization -The provided context does not explicitly mention numerical stabilization techniques like anti-trapping currents for sharp-interface limits. - -## Interface Width Control -The provided context does not explicitly detail the relationship between $\kappa$, interface width ($W$), and mesh size requirements. However, the `DiscreteNucleationMap` user object has an `int_width` parameter for the nucleus interface width . - -## Notes -The MOOSE phase field module is designed to simplify the implementation of phase field models by leveraging common structures like the Cahn-Hilliard and Allen-Cahn equations and free energy functionals . The framework uses PETSc for solving nonlinear equations and offers different solution methods like `NEWTON`, `JFNK`, and `PJFNK` . Preconditioning options such as LU decomposition and Additive Schwartz Method (ASM) are available to improve performance . - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-elastic-coupling.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-elastic-coupling.md deleted file mode 100644 index ab2100d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-elastic-coupling.md +++ /dev/null @@ -1,239 +0,0 @@ ---- -id: moose-pf-elastic-coupling -title: MOOSE Elastic energy coupling with phase field -domain: phase-field -subdomain: algorithmic -tags: -- elastic-energy -- variable-eigenstrain -- two-way-coupling -- khachaturyan -- driving-force -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-phase-field-mechanics-coupling - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-phase-field-mechanics-coupling -- to: cm-kinematics-tl - type: implements - weight: 0.5 - note: Elastic energy feedback into phase field driving force ---- - -# MOOSE Elastic energy coupling with phase field - -The MOOSE framework couples elastic strain energy with phase field evolution primarily through the `ElasticEnergyMaterial` class, which calculates the elastic free energy and its derivatives, and the `ACGrGrElasticDrivingForce` kernel, which incorporates these elastic energy derivatives into the Allen-Cahn equation. Phase-dependent eigenstrains are handled by classes like `ComputeVariableEigenstrain`, which allows the eigenstrain to be a function of order parameters. This creates a two-way coupling where the phase field influences the elastic strain, and the resulting elastic energy feeds back into the phase field evolution. - -## Elastic Energy Contribution to Total Free Energy -The elastic energy contribution, $f_{elastic} = \frac{1}{2} \epsilon^e : C : \epsilon^e$, is added to the total free energy through the `ElasticEnergyMaterial` class . This material computes the elastic free energy density and its derivatives with respect to coupled variables, which can include phase field order parameters . The `computeF()` method within `ElasticEnergyMaterial` calculates this elastic free energy density . - -## Eigenstrain from Phase Transformation -MOOSE defines phase-dependent eigenstrains using material classes derived from `ComputeEigenstrainBase` . Specifically, `ComputeVariableEigenstrain` is designed to make the eigenstrain a function of multiple variables, such as order parameters . - -## `ComputeVariableEigenstrain` and Order Parameter Dependence -The `ComputeVariableEigenstrain` class makes the eigenstrain a function of the order parameter $\eta$ by taking a `prefactor` material property that depends on the coupled variables (`args`) . The `computeQpEigenstrain()` method calculates the eigenstrain as the product of a base tensor and this prefactor . The derivatives of the eigenstrain with respect to the coupled variables are also computed, which are crucial for the two-way coupling . - -## Two-Way Coupling -The two-way coupling is achieved as follows: -1. **Order parameter affects eigenstrain**: The phase field order parameter ($\eta$) influences the eigenstrain through `ComputeVariableEigenstrain` by acting as one of the `args` for the `prefactor` . -2. **Eigenstrain changes stress**: The eigenstrain contributes to the total strain, which in turn affects the stress and elastic energy calculated by the solid mechanics module. -3. **Elastic energy feeds back to PF driving force**: The `ACGrGrElasticDrivingForce` kernel calculates the portion of the Allen-Cahn equation that results from the deformation energy . This kernel requires the elastic strain and the derivative of the elasticity tensor as material properties . The `computeDFDOP()` method in `ACGrGrElasticDrivingForce` computes this driving force . - -## `ElasticEnergyMaterial` and $\partial f_{elastic}/\partial \eta$ -Yes, `ElasticEnergyMaterial` computes $\partial f_{elastic}/\partial \eta$ for the Allen-Cahn equation. It is a `DerivativeFunctionMaterialBase` and its `computeDF()` method calculates the first derivative of the elastic free energy with respect to a coupled variable (e.g., an order parameter $\eta$) . This derivative is then used by kernels like `ACGrGrElasticDrivingForce` to formulate the Allen-Cahn equation. - -## Khachaturyan's Model (Concentration-dependent or Phase-dependent Lattice Mismatch) -MOOSE implements concentration-dependent or phase-dependent lattice mismatch by allowing the eigenstrain to be a function of other variables, such as concentration or order parameters. This is achieved through classes like `ComputeVariableEigenstrain` or `ComputeVariableBaseEigenStrain` . These materials take a `prefactor` that can be defined as a function of concentration or phase field variables, effectively making the eigenstrain (representing lattice mismatch) dependent on these quantities. - -## Implementation: MultiApp or Single-App -The coupling described is typically implemented within a single MOOSE application using coupled variables. The phase field variables and mechanical variables (displacements) are solved simultaneously within the same application. This is evident from the way material properties and their derivatives are fetched and coupled across different modules (e.g., `PhaseFieldApp` and `SolidMechanicsApp`) within the same input file structure . - -## Coupled PDE System - -The general form of the Allen-Cahn equation for an order parameter $\eta_j$ is given by: -$$ -\frac{\partial \eta_j}{\partial t} = - L_j \frac{\delta F}{\delta \eta_j} \label{eq:AC} \quad (1) -$$ -where $F$ is the total free energy functional. When elastic energy is included, $F$ contains an elastic energy term $E_d$ (or $f_{elastic}$) . The functional derivative $\frac{\delta F}{\delta \eta_j}$ will then include $\frac{\partial E_d}{\partial \eta_j}$ . - -The elastic energy density is $f_{elastic} = \frac{1}{2} \epsilon^e : C : \epsilon^e$, where $\epsilon^e = \epsilon - \epsilon^*$ is the elastic strain, $\epsilon$ is the total strain, and $\epsilon^*$ is the eigenstrain. The total strain $\epsilon$ is derived from the displacement field $u$. The eigenstrain $\epsilon^*$ is a function of the order parameter $\eta$. - -The coupled system involves: -1. **Mechanical Equilibrium Equation**: - $$ - \nabla \cdot \sigma = 0 \quad (2) - $$ - where $\sigma = C : \epsilon^e$ is the stress tensor. -2. **Allen-Cahn Equation for Phase Field Evolution**: - $$ - \frac{\partial \eta}{\partial t} = -L \left( \frac{\partial f_{loc}}{\partial \eta} + \frac{\partial f_{elastic}}{\partial \eta} - \nabla \cdot (\kappa \nabla \eta) \right) \quad (3) - $$ - The term $\frac{\partial f_{elastic}}{\partial \eta}$ is the elastic driving force for phase evolution. - -## Classes & Methods - -* `ElasticEnergyMaterial::computeF()`: Computes the elastic free energy density $f_{elastic} = \frac{1}{2} \sigma : \epsilon^e$. -* `ElasticEnergyMaterial::computeDF(unsigned int i_var)`: Computes the first derivative of the elastic free energy density with respect to a coupled variable (e.g., an order parameter $\eta$). -* `ACGrGrElasticDrivingForce::computeDFDOP(PFFunctionType type)`: Calculates the elastic driving force term $\frac{\partial f_{elastic}}{\partial \eta}$ for the Allen-Cahn equation. -* `ComputeVariableEigenstrain::computeQpEigenstrain()`: Calculates the eigenstrain at each quadrature point, making it a function of coupled variables (e.g., order parameters). -* `ComputeVariableEigenstrain::ComputeVariableEigenstrain()`: Fetches derivatives of the prefactor and builds elastic strain derivatives with respect to coupled variables. - -## Parameters - -* `ElasticEnergyMaterial`: - * `base_name`: `string`, "Material property base name" - * `coupled_variables`: `vector`, "Vector of variable arguments of the free energy function" - * `displacement_gradients`: `vector`, "Vector of displacement gradient variables" -* `ComputeVariableEigenstrain`: - * `args`: `vector`, "variable dependencies for the prefactor" (required) -* `ACGrGrElasticDrivingForce`: - * Inherits parameters from `ACBulk`. - -## Relationships - -` ` `mermaid -classDiagram - direction LR - class Material { - +computeQpProperties() - } - class DerivativeMaterialInterface { - } - class ComputeEigenstrainBase { - +computeQpEigenstrain() - } - class ComputeVariableEigenstrain { - -_num_args - -_dprefactor - -_d2prefactor - -_delastic_strain - -_d2elastic_strain - } - class ElasticEnergyMaterial { - -_stress - -_elasticity_tensor - -_strain - +computeF() - +computeDF() - } - class ACBulk { - +computeDFDOP() - } - class ACGrGrElasticDrivingForce { - -_D_elastic_tensor - -_elastic_strain - } - class AllenCahn { - -_dFdEta - -_d2FdEta2 - -_d2FdEtadarg - } - - Material <|-- ComputeEigenstrainBase - DerivativeMaterialInterface <|-- ComputeVariableEigenstrain - ComputeEigenstrainBase <|-- ComputeVariableEigenstrain - DerivativeFunctionMaterialBase <|-- ElasticEnergyMaterial - ACBulk <|-- ACGrGrElasticDrivingForce - ACBulk <|-- AllenCahn - - ComputeVariableEigenstrain ..> MaterialProperty : "sets _eigenstrain" - ElasticEnergyMaterial ..> MaterialProperty : "gets _stress, _elasticity_tensor, _strain" - ACGrGrElasticDrivingForce ..> MaterialProperty : "gets _D_elastic_tensor, _elastic_strain" - - ElasticEnergyMaterial --|> "calculates ∂f_elastic/∂η" ACGrGrElasticDrivingForce - ComputeVariableEigenstrain --|> "defines ε*(η)" ElasticEnergyMaterial -` ` ` - -## MOOSE Input Syntax - -` ` `ini -[Materials] - [./elastic_tensor] - type = ComputeIsotropicElasticityTensor - block = 0 - youngs_modulus = 100e9 - poissons_ratio = 0.3 - [../] - [./eigenstrain_prefactor] - type = GenericFunctionMaterial - prop_names = 'prefactor' - f_name = 'eta' # Assuming 'eta' is the order parameter variable - block = 0 - [../] - [./eigenstrain] - type = ComputeVariableEigenstrain - block = 0 - eigen_base_tensor = '1 0 0 0 1 0 0 0 1' # Isotropic eigenstrain - prefactor = eigenstrain_prefactor/prefactor - args = eta # Coupled to the order parameter 'eta' - [../] - [./elastic_energy] - type = ElasticEnergyMaterial - block = 0 - coupled_variables = eta # Coupled to the order parameter 'eta' - displacement_gradients = 'disp_x_grad_x disp_x_grad_y disp_x_grad_z disp_y_grad_x disp_y_grad_y disp_y_grad_z disp_z_grad_x disp_z_grad_y disp_z_grad_z' - elasticity_tensor = elastic_tensor/elasticity_tensor - elastic_strain = total_elastic_strain # This is the elastic strain (total - eigen) - [../] -[] - -[Kernels] - [./ac_elastic_driving_force] - type = ACGrGrElasticDrivingForce - variable = eta - block = 0 - elastic_tensor_derivative = elastic_energy/delasticity_tensor_d_eta # Derivative of C w.r.t. eta - elastic_strain = elastic_energy/elastic_strain # Elastic strain - [../] - [./ac_bulk] - type = AllenCahn - variable = eta - block = 0 - f_name = free_energy_material/f_local # Local free energy contribution - [../] -[] - -[Functions] - [./free_energy_function] - type = ParsedFunction - value = 'f_local(eta)' # Define your local free energy function - [../] -[] - -[Problem] - type = Reference - coord_type = XYZ - [./Executioner] - type = Transient - solve_type = 'NEWTON' - [../] -[] - -[Variables] - [./disp_x] - type = Displacement - order = FIRST - family = LAGRANGE - [../] - [./disp_y] - type = Displacement - order = FIRST - family = LAGRANGE - [../] - [./disp_z] - type = Displacement - order = FIRST - family = LAGRANGE - [../] - [./eta] - type = OrderParameter - order = FIRST - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-energy-coded.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-energy-coded.md deleted file mode 100644 index 18f3faf..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-energy-coded.md +++ /dev/null @@ -1,273 +0,0 @@ ---- -id: moose-pf-energy-coded -title: MOOSE Custom free energy materials without parsing -domain: phase-field -subdomain: algorithmic -tags: -- DerivativeMaterialInterface -- CALPHAD -- sublattice -- custom-free-energy -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-derivative-parsed-material - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-derivative-parsed-material ---- - -# MOOSE Custom free energy materials without parsing - -MOOSE handles coded (C++) free energy materials through the `DerivativeMaterialInterface` and `DerivativeFunctionMaterialBase` classes, which allow you to define a free energy function and its derivatives. Kernels like `AllenCahn` and `SplitCHParsed` then consume these registered derivatives. - -## Classes & Methods - -### `DerivativeMaterialInterface` -The `DerivativeMaterialInterface` class is a veneer that provides methods for declaring and retrieving derivative material properties. - -### `DerivativeFunctionMaterialBase` -The `DerivativeFunctionMaterialBase` class is a base class for materials that compute a function and its derivatives. - -#### Methods to Implement in a Custom Material -When implementing a custom material that inherits from `DerivativeFunctionMaterialBase`, you must override the following methods to define your free energy function and its derivatives: -* `computeF()`: Overridden to provide the free energy function. -* `computeDF(unsigned int arg)`: Overridden to calculate the first derivatives. -* `computeD2F(unsigned int arg1, unsigned int arg2)`: Overridden to calculate the second derivatives. -* `computeD3F(unsigned int, unsigned int, unsigned int)`: Optionally overridden to calculate the third derivatives. - -### `DerivativeMaterialPropertyNameInterface` -This interface provides helper functions to generate material property names for arbitrary derivatives. - -#### Naming Convention for Derivative Properties -The naming convention for derivative properties is handled by helper functions in `DerivativeMaterialPropertyNameInterface`. -* `derivativePropertyNameFirst(const MaterialPropertyName & base, const SymbolName & c1)`: Generates the name for the first derivative, e.g., `d{base}/d{c1}`. -* `derivativePropertyNameSecond(const MaterialPropertyName & base, const SymbolName & c1, const SymbolName & c2)`: Generates the name for the second derivative, e.g., `d2{base}/d{c1}d{c2}`. -* `derivativePropertyNameThird(const MaterialPropertyName & base, const SymbolName & c1, const SymbolName & c2, const SymbolName & c3)`: Generates the name for the third derivative. - -### `DerivativeMaterialInterface::getMaterialPropertyDerivative()` -This method is used to retrieve derivative material properties. It has several overloads to handle different ways of specifying the variables with respect to which the derivative is taken. For example, you can retrieve a derivative by providing the base property name and the names of the coupled variables, or by using indices into the `_coupled_standard_moose_vars` vector. - -` ` `cpp -template -const GenericMaterialProperty & -DerivativeMaterialInterface::getMaterialPropertyDerivative(const std::string & base, - const SymbolName & c1, - unsigned int v2, - unsigned int v3) -{ - return getMaterialPropertyDerivative( - base, - c1, - this->_coupled_standard_moose_vars[v2]->name(), - v3 == libMesh::invalid_uint ? "" : this->_coupled_standard_moose_vars[v3]->name()); -} -` ` ` -This snippet shows an overload that takes a `SymbolName` for the first variable and `unsigned int` indices for the second and third variables. It converts the `unsigned int` indices to variable names using `this->_coupled_standard_moose_vars[vX]->name()`. - -## Example: Implementing a CALPHAD-type Gibbs energy with sublattice models in C++ - -To implement a custom free energy, you would create a new C++ class that inherits from `DerivativeFunctionMaterialBase`. - -` ` `cpp -// In your custom material's header file (e.g., MyCalphadMaterial.h) -#pragma once - -#include "DerivativeFunctionMaterialBase.h" - -class MyCalphadMaterial : public DerivativeFunctionMaterialBase -{ -public: - static InputParameters validParams(); - MyCalphadMaterial(const InputParameters & parameters); - -protected: - virtual Real computeF() override; - virtual Real computeDF(unsigned int arg) override; - virtual Real computeD2F(unsigned int arg1, unsigned int arg2) override; - virtual Real computeD3F(unsigned int arg1, unsigned int arg2, unsigned int arg3) override; - -private: - // Declare coupled variables for concentrations, temperature, etc. - const VariableValue & _c1; - const VariableValue & _c2; - const VariableValue & _temp; - - unsigned int _c1_var; - unsigned int _c2_var; - unsigned int _temp_var; -}; -` ` ` - -` ` `cpp -// In your custom material's source file (e.g., MyCalphadMaterial.C) -#include "MyCalphadMaterial.h" - -registerMooseObject("MyPhaseFieldApp", MyCalphadMaterial); - -InputParameters -MyCalphadMaterial::validParams() -{ - InputParameters params = DerivativeFunctionMaterialBase::validParams(); - params.addClassDescription("Custom CALPHAD-type Gibbs Free Energy Material"); - params.addRequiredCoupledVar("c1", "First concentration variable"); - params.addRequiredCoupledVar("c2", "Second concentration variable"); - params.addRequiredCoupledVar("temperature", "Temperature variable"); - return params; -} - -MyCalphadMaterial::MyCalphadMaterial(const InputParameters & parameters) - : DerivativeFunctionMaterialBase(parameters), - _c1(coupledValue("c1")), - _c2(coupledValue("c2")), - _temp(coupledValue("temperature")), - _c1_var(coupled("c1")), - _c2_var(coupled("c2")), - _temp_var(coupled("temperature")) -{ -} - -Real -MyCalphadMaterial::computeF() -{ - // Implement your CALPHAD Gibbs energy function here - // Example: G = c1*ln(c1) + c2*ln(c2) + (1-c1-c2)*ln(1-c1-c2) + ... - const Real c1 = _c1[_qp]; - const Real c2 = _c2[_qp]; - const Real temp = _temp[_qp]; - // ... complex CALPHAD expression ... - return c1 * std::log(c1) + c2 * std::log(c2) + (1.0 - c1 - c2) * std::log(1.0 - c1 - c2) + temp; // Placeholder -} - -Real -MyCalphadMaterial::computeDF(unsigned int arg) -{ - // Implement the first derivative of computeF with respect to the variable 'arg' - if (arg == _c1_var) - { - // dF/dc1 - return std::log(_c1[_qp]) + 1.0 - std::log(1.0 - _c1[_qp] - _c2[_qp]) - 1.0; // Placeholder - } - if (arg == _c2_var) - { - // dF/dc2 - return std::log(_c2[_qp]) + 1.0 - std::log(1.0 - _c1[_qp] - _c2[_qp]) - 1.0; // Placeholder - } - if (arg == _temp_var) - { - // dF/dT - return 1.0; // Placeholder - } - return 0.0; -} - -Real -MyCalphadMaterial::computeD2F(unsigned int arg1, unsigned int arg2) -{ - // Implement the second derivative of computeF - if (arg1 == _c1_var && arg2 == _c1_var) - { - // d2F/dc1dc1 - return 1.0 / _c1[_qp] + 1.0 / (1.0 - _c1[_qp] - _c2[_qp]); // Placeholder - } - if (arg1 == _c1_var && arg2 == _c2_var) - { - // d2F/dc1dc2 - return 1.0 / (1.0 - _c1[_qp] - _c2[_qp]); // Placeholder - } - // ... and so on for all combinations - return 0.0; -} - -Real -MyCalphadMaterial::computeD3F(unsigned int arg1, unsigned int arg2, unsigned int arg3) -{ - // Implement the third derivative of computeF (optional) - return 0.0; -} -` ` ` - -## Registering Derivatives for Kernels - -Kernels like `AllenCahn` and `SplitCHParsed` consume derivatives by requesting them from the material system using `getMaterialPropertyDerivative()`. - -For example, in `AllenCahn`, the first and second derivatives of the free energy `f_name` with respect to the order parameter `_var.name()` are retrieved: -` ` `cpp -AllenCahn::AllenCahn(const InputParameters & parameters) - : ACBulk(parameters), - _dFdEta(getMaterialPropertyDerivative("f_name", _var.name())), - _d2FdEta2(getMaterialPropertyDerivative("f_name", _var.name(), _var.name())), - _d2FdEtadarg(_n_args) -{ - // Iterate over all coupled variables - for (unsigned int i = 0; i < _n_args; ++i) - _d2FdEtadarg[i] = &getMaterialPropertyDerivative("f_name", _var.name(), i); -} -` ` ` -Here, `_dFdEta` stores $\frac{\partial F}{\partial \eta}$ and `_d2FdEta2` stores $\frac{\partial^2 F}{\partial \eta^2}$. The loop then retrieves mixed second derivatives $\frac{\partial^2 F}{\partial \eta \partial arg_i}$ for all other coupled variables. - -The `DerivativeFunctionMaterialBase` class automatically declares and registers these derivative properties based on the `computeF`, `computeDF`, `computeD2F`, and `computeD3F` methods you implement. When a kernel requests a derivative using `getMaterialPropertyDerivative()`, the material system looks up the corresponding property that was computed by your custom material. - -## Relationships - -` ` `mermaid -classDiagram - class Material { - +computeQpProperties() - } - class DerivativeMaterialPropertyNameInterface { - +derivativePropertyNameFirst() - +derivativePropertyNameSecond() - +derivativePropertyNameThird() - } - class DerivativeMaterialInterface { - +getMaterialPropertyDerivative() - +declarePropertyDerivative() - } - class FunctionMaterialBase { - +computeProperties() - } - class DerivativeFunctionMaterialBase { - +computeF() - +computeDF(arg) - +computeD2F(arg1, arg2) - +computeD3F(arg1, arg2, arg3) - } - class AllenCahn { - -_dFdEta - -_d2FdEta2 - -_d2FdEtadarg - } - class SplitCHParsed { - -_dFdc - -_d2Fdc2 - -_d2Fdcdarg - } - class MyCalphadMaterial { - +computeF() - +computeDF(arg) - +computeD2F(arg1, arg2) - +computeD3F(arg1, arg2, arg3) - } - - DerivativeMaterialInterface <|-- DerivativeFunctionMaterialBase : public - DerivativeMaterialPropertyNameInterface <|-- DerivativeMaterialInterface : public - FunctionMaterialBase <|-- DerivativeFunctionMaterialBase : public - DerivativeMaterialInterface <|-- AllenCahn : public - DerivativeMaterialInterface <|-- SplitCHParsed : public - DerivativeFunctionMaterialBase <|-- MyCalphadMaterial : public - - AllenCahn ..> DerivativeMaterialInterface : uses getMaterialPropertyDerivative() - SplitCHParsed ..> DerivativeMaterialInterface : uses getMaterialPropertyDerivative() - MyCalphadMaterial ..> Material : provides properties -` ` ` - -## Notes -The `DerivativeParsedMaterial` is a related class that automatically performs symbolic differentiation for free energy functions defined by string expressions in the input file. However, the user's query specifically asks about cases "too complex for string parsing," which points to implementing a custom C++ material inheriting from `DerivativeFunctionMaterialBase`. The `MathFree - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-energy-parsing.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-energy-parsing.md deleted file mode 100644 index 1ee319c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-energy-parsing.md +++ /dev/null @@ -1,153 +0,0 @@ ---- -id: moose-pf-energy-parsing -title: MOOSE Free energy parsing system -domain: phase-field -subdomain: algorithmic -tags: -- DerivativeParsedMaterial -- fparser -- symbolic-differentiation -- JIT -- coupled-variables -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-derivative-parsed-material - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-derivative-parsed-material ---- - -# MOOSE Free energy parsing system - -The MOOSE framework provides a robust system for parsing free energy expressions and automatically computing their derivatives, primarily through the `DerivativeParsedMaterial` class . This system leverages the `fparser` library for symbolic differentiation and allows for flexible definition of expressions, material properties, and coupled variables . - -## Classes & Methods - -* `DerivativeParsedMaterial` : A material class that evaluates a parsed function and automatically provides its derivatives. -* `DerivativeParsedMaterialHelperTempl::functionsPostParse()` : This method sets up variables and initiates the derivative generation process after the primary function has been parsed. -* `DerivativeParsedMaterialHelperTempl::assembleDerivatives()` : Handles the assembly of the computed derivatives. -* `FunctionMaterialPropertyDescriptor` : Parses and describes material properties, including their dependencies and derivation state. -* `DerivativeSumMaterial` : A meta-material class designed to combine multiple derivative materials, effectively summing up various free energy contributions. - -## `DerivativeParsedMaterial` and Automatic Differentiation - -The `DerivativeParsedMaterial` class automatically computes derivatives of a user-defined string expression . It achieves this by using the `fparser` library, specifically `libmesh/fparser_ad.hh` , which provides symbolic differentiation capabilities. When you define an `expression` in your input file, `DerivativeParsedMaterial` parses this expression and then, based on the `derivative_order` parameter, generates the required first, second, and potentially third-order derivatives . - -For example, if you provide an expression $f(\eta, c)$, the system can compute $\frac{\partial f}{\partial \eta}$, $\frac{\partial^2 f}{\partial \eta^2}$, $\frac{\partial^2 f}{\partial \eta \partial c}$, and so on . The `functionsPostParse()` method in `DerivativeParsedMaterialHelperTempl` is responsible for setting up the symbols and then triggering the derivative generation . - -## `FunctionParserBase` / `fparser` Backend - -The symbolic differentiation library used is `fparser`, specifically the `libmesh/fparser_ad.hh` header . This library allows MOOSE to parse mathematical expressions provided as strings and then symbolically differentiate them to obtain the required derivatives. - -## Referencing Material Property Names - -Material property names are referenced within parsed expressions using the `material_property_names` parameter . The `FunctionMaterialPropertyDescriptor` class is used to parse these names and understand their dependencies . - -The syntax for `material_property_names` is flexible: -* `F`: A material property `F` with no declared variable dependencies. -* `F(c,phi)`: A material property `F` dependent on variables `c` and `phi`. -* `d3x:=D[x(a,b),a,a,b]`: Defines a third derivative $\frac{\partial^3x}{\partial^2a\partial b}$ of material property `x` and assigns it the name `d3x` for use in the expression. -* `dF:=D[F,c]`: Derivative of `F` with respect to `c`. -* `F_old:=Old[F]` or `F_older:=Older[F]`: Accesses previous time step values of `F`. - - - -## Coupling Between Parsed Materials - -One `DerivativeParsedMaterial` can reference another by listing its output property name in its `material_property_names` parameter . For example, in the `GrandPotentialMultiphase.i` test, `omegab` references `Vm`, `kb`, and `cbeq`, which could be properties provided by other materials . The system automatically pulls in the necessary derivatives of these coupled material properties when constructing the derivatives of the parsed function . - -## `DerivativeSumMaterial` - -The `DerivativeSumMaterial` class is designed to combine multiple free energy contributions . It takes a list of material names via the `sum_materials` parameter and sums their contributions, potentially with prefactors and a constant term . - -### Parameters -* `sum_materials` (vector of strings): Base names of the parsed sum material properties . -* `coupled_variables` (vector of strings): Names of variables being summed . -* `prefactor` (vector of Reals, default: `{}`): Prefactor to multiply each sum term with . -* `constant` (Real, default: `0.0`): Constant to be added to the prefactor multiplied sum . - -## Performance: JIT-compilation and Caching - -The parsed expressions can be JIT-compiled for performance . The `enable_jit` parameter controls this behavior . Derivatives are also cached internally to avoid redundant computations. - -## Derivative Depth - -The `DerivativeParsedMaterial` can automatically compute derivatives up to the third order . The maximum order is controlled by the `derivative_order` parameter . Only required derivatives are evaluated . - -### Parameters -* `derivative_order` (unsigned int, default: `3`): Maximum order of derivatives to be taken . - -## `coupled_variables` Parameter - -The `coupled_variables` parameter maps variable names to symbols in the expression . These are the primary variables with respect to which derivatives are always taken . - -### Parameters -* `coupled_variables` (vector of strings): Vector of names of variables used in the parsed function . - -## Example Usage Pattern - -Here's an example of a free energy expression using `DerivativeParsedMaterial` from a MOOSE input file : - -` ` `ini -[Materials] - [local_energy] - type = DerivativeParsedMaterial - block = 0 - f_name = f_loc - args = c - constant_names = 'A B C D E F G eV_J d' - constant_expressions = '-2.446831e+04 -2.827533e+04 4.167994e+03 7.052907e+03 - 1.208993e+04 2.568625e+03 -2.354293e+03 - 6.24150934e+18 1e-27' - function = 'eV_J*d*(A*c+B*(1-c)+C*c*log(c)+D*(1-c)*log(1-c)+ - E*c*(1-c)+F*c*(1-c)*(2*c-1)+G*c*(1-c)*(2*c-1)^2)' - [] -[] -` ` ` - - -In this example: -* `type = DerivativeParsedMaterial` specifies the material class . -* `f_name = f_loc` gives a name to the free energy function . -* `args = c` defines `c` as a coupled variable (though `coupled_variables` is the more explicit parameter) . -* `constant_names` and `constant_expressions` define constants used in the expression . -* `function` (or `expression`) contains the free energy formula . - -## Relationships - -` ` `mermaid -classDiagram - class MooseObject - class Material - class ParsedMaterialBase - class ParsedMaterialHelper - class DerivativeParsedMaterialHelper - class DerivativeParsedMaterial - class DerivativeSumMaterial - class FunctionMaterialPropertyDescriptor - class DerivativeMaterialPropertyNameInterface - - MooseObject <|-- Material - Material <|-- ParsedMaterialBase - ParsedMaterialBase <|-- ParsedMaterialHelper - ParsedMaterialHelper <|-- DerivativeParsedMaterialHelper - DerivativeParsedMaterialHelper <|-- DerivativeParsedMaterial - Material <|-- DerivativeSumMaterial - - DerivativeMaterialPropertyNameInterface <|-- FunctionMaterialPropertyDescriptor - - DerivativeParsedMaterialHelper "1" *-- "1" FunctionMaterialPropertyDescriptor : uses - DerivativeParsedMaterialHelper "1" *-- "1" libmesh::fparser_ad : uses -` ` ` - -## Notes - -The `ParsedMaterialBase` class provides the fundamental parsing capabilities for expressions, constants, and material properties . `DerivativeParsedMaterial` extends this by adding automatic differentiation . The `additional_derivative_symbols` parameter allows specifying extra symbols (beyond coupled variables) for which derivatives should be computed . The `DerivativeFunctionMaterialBase` is a more general base class for materials that compute functions and their derivatives, which `DerivativeParsedMaterial` ultimately builds upon . - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-grain-growth.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-grain-growth.md deleted file mode 100644 index 017d8c3..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-grain-growth.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -id: moose-pf-grain-growth -title: MOOSE Grain growth and coarsening -domain: phase-field -subdomain: algorithmic -tags: -- grain-growth -- coarsening -- fan-chen -- grain-tracker-remap -- zener-pinning -- abnormal -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-nucleation-grain-growth - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-nucleation-grain-growth ---- - -# MOOSE Grain growth and coarsening - -MOOSE simulates grain growth and Ostwald ripening primarily through the phase-field method, utilizing a multi-order-parameter approach based on the Fan-Chen model. The `GrainTracker` object plays a crucial role in managing the order parameters, allowing the simulation to track more grains than the number of order parameters by remapping them as needed. Anisotropic grain boundary properties and various driving forces can be incorporated into the model. - -## Multi-order-parameter grain growth: the Fan-Chen or similar model - -MOOSE implements a multiphase grain growth model based on the work of Chen and Yang, and Moelans et al. . This model uses a system of Allen-Cahn equations to describe grain boundary migration . The evolution of each grain's order parameter ($\eta_i$) is governed by the equation: -$$ -\frac{\partial \eta_i}{\partial t} = - L \frac{\delta F}{\delta \eta_i} \quad (1) -$$ -where $F$ is the free energy functional and $L$ is the order parameter mobility . The free energy functional includes a local free energy density ($f_{loc}$), additional energy density sources ($f_{add}$), and a gradient term: -$$ -F = \int_V f_{loc}(\eta_0, \eta_1, \ldots, \eta_N) + f_{add} (\eta_0, \eta_1, \ldots, \eta_N) + \kappa \sum^N_i |\nabla \eta_i|^2 \quad (2) -$$ -For grain growth, the local free energy density is defined as: -$$ -f_{loc} = \mu \left( \sum_i^N \left(\frac{\eta_i^4}{4} - \frac{\eta_i^2}{2} \right) + \gamma \sum_{i=1}^N \sum_{j>i}^N \eta_i^2 \eta_j^2 + \frac{1}{4} \right) \quad (3) -$$ -Here, $N$ is the total number of order parameters, $\mu$ is the free energy weight, and $\gamma=1.5$ for symmetric interfacial profiles . - -The model parameters $L$, $\mu$, and $\kappa$ are related to the grain boundary energy ($\sigma$), diffuse grain boundary width ($w_{GB}$), and grain boundary mobility ($M_{GB}$) . - -The number of order parameters typically corresponds to the number of grains being simulated. However, the `GrainTracker` allows for simulating more grains than order parameters. - -## `GrainTracker` — how does it remap order parameters to track more grains than order parameters? - -The `GrainTracker` is a `Postprocessor` that enables the simulation of polycrystal grain growth with a number of grains exceeding the number of order parameters . It achieves this by remapping order parameters to different grains as needed to prevent unphysical grain coalescence when grains represented by the same variable come into contact . - -### Classes & Methods: -* `GrainTracker::GrainTracker(const InputParameters & parameters)`: Constructor for the `GrainTracker` class . -* `GrainTracker::validParams()`: Defines the input parameters for the `GrainTracker` object . -* `GrainTracker::initialize()`: Initializes the `GrainTracker` object . -* `GrainTracker::execute()`: Performs the grain tracking and remapping logic . -* `GrainTracker::finalize()`: Finalizes the `GrainTracker` object . -* `GrainTracker::assignGrains()`: Assigns a unique ID to each `FeatureData` object (grain) during the initial tracking phase . -* `GrainTracker::trackGrains()`: Compares incoming `FeatureData` objects with previous time step information to track grains over time . -* `GrainTracker::remapGrains()`: Remaps grains that are too close to each other to different order parameters . -* `GrainTracker::attemptGrainRenumber(FeatureData & grain, unsigned int depth, unsigned int max_depth)`: A recursive function that attempts to remap a grain to a new index . -* `GrainTracker::swapSolutionValues(FeatureData & grain, std::size_t new_var_index, std::vector> & cache, RemapCacheMode cache_mode)`: Moves solution values from a given grain to a new variable number during remapping . -* `FauxGrainTracker`: A lightweight replacement for `GrainTracker` when remapping is not needed, suitable when the number of grains is less than or equal to the number of order parameters . - -### Algorithm Steps: -The `GrainTracker`'s remapping algorithm is executed within the `remapGrains()` method . - -` ` `pseudocode -FUNCTION remapGrains() - grains_remapped = true - WHILE grains_remapped IS TRUE - grains_remapped = false - notify_ids.clear() - - FOR EACH grain1 IN _feature_sets - // Remap grains on reserved order parameters - IF grain1._var_index >= _reserve_op_index THEN - IF _verbosity_level > 0 THEN - PRINT "Grain #", grain1._id, " detected on a reserved order parameter #", grain1._var_index, ", remapping to another variable" - END IF - FOR max FROM 0 TO _max_remap_recursion_depth - IF attemptGrainRenumber(grain1, 0, max) THEN - BREAK - END IF - END FOR - IF NOT attemptGrainRenumber(grain1, 0, _max_remap_recursion_depth + 1) THEN - ERROR "Unable to find suitable order parameters for remapping for Grain #", grain1._id - END IF - grains_remapped = true - END IF - - FOR EACH grain2 IN _feature_sets - IF grain1 IS grain2 THEN CONTINUE - IF grain1._var_index == grain2._var_index AND // Grains represented by same variable - grain1._id != grain2._id AND // Different grains - grain1.boundingBoxesIntersect(grain2) AND // Bounding boxes intersect - grain1.halosIntersect(grain2) THEN // Halos actually overlap - IF _verbosity_level > 0 THEN - PRINT "Grain #", grain1._id, " intersects Grain #", grain2._id, " (variable index: ", grain1._var_index, ")" - END IF - FOR max FROM 0 TO _max_remap_recursion_depth - IF attemptGrainRenumber(grain1, 0, max) THEN - grains_remapped = true - BREAK - END IF - END FOR - IF NOT attemptGrainRenumber(grain1, 0, _max_remap_recursion_depth + 1) AND - NOT attemptGrainRenumber(grain2, 0, _max_remap_recursion_depth + 1) THEN - notify_ids.insert(grain1._id) - notify_ids.insert(grain2._id) - END IF - END IF - END FOR - END FOR - - IF notify_ids IS NOT EMPTY THEN - IF _tolerate_failure THEN - WARNING "Unable to find suitable order parameters for remapping for grain IDs: ", notify_ids - ELSE - ERROR "Unable to find suitable order parameters for remapping for grain IDs: ", notify_ids - END IF - END IF - END WHILE -END FUNCTION -` ` ` - -### Parameters: -* `remap = true/false`: Boolean parameter to enable or disable grain remapping . -* `_reserve_op_index`: The index above which order parameters are considered reserved and trigger remapping if a grain is found on them . -* `_max_remap_recursion_depth`: The maximum recursion depth for the `attemptGrainRenumber` method . -* `_tolerate_failure`: If `true`, the simulation will issue a warning instead of an error if remapping fails . - -### Relationships: -` ` `mermaid -classDiagram - class FeatureFloodCount { - +execute() - #_feature_sets - } - class GrainTracker { - +remapGrains() - #_feature_sets_old - #_remap - #_tolerate_failure - #_reserve_op_index - #_max_remap_recursion_depth - #attemptGrainRenumber() - #swapSolutionValues() - } - class GrainTrackerInterface { - <> - +getFeatureVar() - +getGrainCentroid() - } - class PolycrystalUserObjectBase { - #prepopulateState() - } - - GrainTracker --|> FeatureFloodCount : extends - GrainTracker --|> GrainTrackerInterface : implements - GrainTracker "1" -- "1" PolycrystalUserObjectBase : uses > _poly_ic_uo - FeatureFloodCount "1" *-- "many" FeatureData : contains - GrainTracker "1" *-- "many" FeatureData : _feature_sets_old -` ` ` - -## Grain boundary energy: how is anisotropic GB energy specified? - -While the basic grain growth model assumes isotropic grain boundary properties , MOOSE provides the `GBAnisotropy` material to define parameters $L$, $\mu$, and $\kappa$ considering misorientation dependence for the GB energy . This allows for specifying anisotropic grain boundary energy. - -## Grain boundary mobility: isotropic vs anisotropic, temperature-dependent - -### Isotropic Mobility -For isotropic grain boundary mobility, the model parameters $L$, $\mu$, and $\kappa$ are defined in terms of the grain boundary energy ($\sigma$), diffuse grain boundary width ($w_{GB}$), and grain boundary mobility ($M_{GB}$) . The `GBEvolution` material defines these parameters assuming isotropic properties . - -### Anisotropic Mobility -Anisotropic mobilities can be specified using the `anisotropic` parameter in actions like `GrandPotentialKernelAction` . The `GBAnisotropy` material also allows for misorientation-dependent grain boundary properties - -Wiki pages you might want to explore: -- [Physics Modules (idaholab/moose)](https://deepwiki.com/idaholab/moose#5) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-multi-component.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-multi-component.md deleted file mode 100644 index 15d8db7..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-multi-component.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -id: moose-pf-multi-component -title: MOOSE Multi-component (multi-species) phase field -domain: phase-field -subdomain: algorithmic -tags: -- multi-component -- cahn-hilliard -- split-CH -- mobility-matrix -- ternary-alloy -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-multi-phase-component - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-multi-phase-component ---- - -# MOOSE Multi-component (multi-species) phase field - -ERROR: Request timed out after 120.0s diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-multi-phase.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-multi-phase.md deleted file mode 100644 index 0f91bd7..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-multi-phase.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: moose-pf-multi-phase -title: MOOSE Multi-phase field models in MOOSE -domain: phase-field -subdomain: algorithmic -tags: -- multi-phase -- switching-function -- multi-well -- grain-tracker -- order-parameter-constraint -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-multi-phase-component - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-multi-phase-component ---- - -# MOOSE Multi-phase field models in MOOSE - -MOOSE handles multi-phase field problems by employing multiple order parameters, specialized interpolation functions, and various constraint enforcement mechanisms. It supports an arbitrary number of phases and grains through a flexible material and kernel system. - -## 1. Multiple Order Parameters ($\eta_1, \eta_2, ..., \eta_n$) -MOOSE uses multiple order parameters, typically one per phase or per grain, to represent different phases or grains in a multi-phase system . For grain growth models, the evolution of each grain's order parameter is defined by the Allen-Cahn equation . - -## 2. Interpolation Functions $h(\eta)$ and $g(\eta_1,...,\eta_n)$ -MOOSE constructs multi-phase interpolation using switching functions, denoted as $h(\eta)$, and barrier functions, denoted as $g(\eta)$. - -### Switching Functions $h(\eta)$ -The `SwitchingFunctionMultiPhaseMaterial` class calculates a switching function for a given phase in a multi-phase, multi-order parameter system . The formulation for phase $\alpha$ is given by: -$$ h_\alpha = \frac{\sum_i \eta_{\alpha i}^2}{\sum_\rho \sum_i \eta_{\rho i}^2} $$ -where $i$ indexes grains of a phase and $\rho$ indexes phases . - -For three-phase systems, the `SwitchingFunction3PhaseMaterial` provides a specific switching function to prevent the formation of a third phase at a two-phase interface . The formula is: -$$ h_i = \frac{\eta_i^2}{4} [15 (1-\eta_i) [1 + \eta_i - (\eta_k - \eta_j)^2] + \eta_i (9\eta_i^2 - 5)] $$ -This can also be constrained to the range $[0,1]$ . - -### Barrier Functions $g(\eta_1,...,\eta_n)$ -The `MultiBarrierFunctionMaterial` provides a double-well phase transformation barrier free energy contribution . A common form is: -$$ g(\vec\eta) = \sum_i \eta_i^2(1-\eta_i)^2 $$ . This material can be configured with different polynomial orders for the barrier function . - -## 3. `SwitchingFunctionMaterial` - Available Switching Functions -MOOSE provides several switching functions: -* `SwitchingFunctionMultiPhaseMaterial`: A general switching function for multi-phase, multi-order parameter systems, based on Moelans, Acta Mat., v 59, p.1077-1086 (2011) . -* `SwitchingFunction3PhaseMaterial`: Specifically designed for three-phase systems to suppress the formation of a third phase at two-phase interfaces . -* `MixedSwitchingFunctionMaterial`: Supports mixed switching functions with adjustable weights . - -## 4. Multi-well Potentials: Barrier Function Extension to N Phases -The barrier function is extended to N phases through classes like `MultiBarrierFunctionMaterial` . This material takes a vector of order parameters (`etas`) and computes a barrier function, typically a sum of individual well functions for each order parameter . The `g_order` parameter allows specifying the polynomial order of the switching function . - -## 5. Constraint Enforcement: $\sum_i \eta_i = 1$ -MOOSE enforces the constraint $\sum_i \eta_i = 1$ primarily through a Lagrange multiplier approach . - -### Lagrange Multiplier -The `SwitchingFunctionConstraintLagrange` kernel is used to constrain the sum of all switching functions in a multiphase system . It acts on a Lagrange multiplier variable (`lambda`) . The residual for this kernel is calculated as: -$$ \mathcal{R} = \psi_m \left( \sum_{i=0}^{N-1} h_i - 1 - \epsilon \lambda \right) $$ -where $h_i$ are the switching functions, $\lambda$ is the Lagrange multiplier, and $\epsilon$ is a shift factor to avoid a zero pivot . - -### Penalty Method -A penalty-based constraint is also available for keeping the sum of all phase order parameters equal to one . - -## 6. `GrainTracker` UserObject -The `GrainTracker` UserObject identifies and tracks individual grains . The provided context does not contain details on its internal mechanism for identification and tracking. - -## 7. Phase-Specific Material Properties -MOOSE weights phase-specific material properties by phase fraction using switching functions. For instance, in the KKS multi-phase model, the global concentration `c` is a weighted sum of phase concentrations `c_i` using switching functions `h_i` : -$$ c = h_1(\eta_1,\eta_2,\eta_3,...) c_1 + h_2(\eta_1,\eta_2,\eta_3,...) c_2 + h_3(\eta_1,\eta_2,\eta_3,..) c_3 + ... $$ . - -The `DerivativeMultiPhaseMaterial` combines an arbitrary number of phase free energies into a global free energy using switching functions . The derivative of the total free energy with respect to an order parameter $\eta_i$ involves the switching function and the phase-specific free energy . - -## Classes & Methods - -* `SwitchingFunctionMultiPhaseMaterialTempl::validParams()`: Defines valid parameters for the multi-phase switching function material . -* `SwitchingFunctionMultiPhaseMaterialTempl::SwitchingFunctionMultiPhaseMaterialTempl()`: Constructor for the multi-phase switching function material, initializing properties and derivatives . -* `SwitchingFunction3PhaseMaterial::validParams()`: Defines valid parameters for the three-phase switching function material . -* `SwitchingFunction3PhaseMaterial::SwitchingFunction3PhaseMaterial()`: Constructor for the three-phase switching function material, parsing the switching function expression . -* `MultiBarrierFunctionMaterial::validParams()`: Defines valid parameters for the multi-barrier function material . -* `MultiBarrierFunctionMaterial::MultiBarrierFunctionMaterial()`: Constructor for the multi-barrier function material, initializing properties and derivatives . -* `MultiBarrierFunctionMaterial::computeQpProperties()`: Computes the barrier function value at quadrature points . -* `SwitchingFunctionConstraintLagrange::validParams()`: Defines valid parameters for the Lagrange multiplier constraint kernel . -* `SwitchingFunctionConstraintLagrange::computeQpResidual()`: Computes the residual for the Lagrange multiplier constraint . -* `KKSMultiPhaseConcentration::validParams()`: Defines valid parameters for the KKS multi-phase concentration kernel . -* `DerivativeMultiPhaseBase::validParams()`: Defines valid parameters for the base class for multi-phase derivative materials . -* `DerivativeMultiPhaseMaterial::computeDF()`: Computes the first derivative of the total free energy with respect to a variable . - -## Equations - -### Switching Function for Multi-Phase Systems -For phase $\alpha$, the switching function is: -$$ h_\alpha = \frac{\sum_i \eta_{\alpha i}^2}{\sum_\rho \sum_i \eta_{\rho i}^2} $$ -where $i$ indexes grains of a phase and $\rho$ indexes phases . - -### Switching Function for Three-Phase Systems -The switching function for three phases is: -$$ h_i = \frac{\eta_i^2}{4} [15 (1-\eta_i) [1 + \eta_i - (\eta_k - \eta_j)^2] + \eta_i (9\eta_i^2 - 5)] $$ . - -### Multi-Well Barrier Function -A common form for the multi-well barrier function is: -$$ g(\vec\eta) = \sum_i \eta_i^2(1-\eta_i)^2 $$ . - -### KKS Multi-Phase Concentration -The global concentration $c$ is related to phase concentrations $c_i$ and switching functions $h_i$ by: -$$ c = h_1(\eta_1,\eta_2,\eta_3,...) c_1 + h_2(\eta_1,\eta_2,\eta_3,...) c_2 + h_3(\eta_1,\eta_2,\eta_3,..) c_3 + ... $$ . - -### Allen-Cahn Equation for Grain Growth -The evolution of each grain's order parameter $\eta_i$ is defined by the Allen-Cahn equation: -$$ \frac{\partial \eta_i}{\partial t} = - L \frac{\delta F}{\delta \eta_i} $$ -where $F$ is the free energy functional and $L$ is the order parameter mobility . - -## Parameters - -* `SwitchingFunctionMultiPhaseMaterial`: - * `h_name`: Name of the switching function material property for the given phase (MaterialPropertyName, required) . - * `phase_etas`: Vector of order parameters for the given phase (CoupledVar, required) . - * `all_etas`: Vector of all order parameters for all phases (CoupledVar, required) . -* `SwitchingFunction3PhaseMaterial`: - * `eta_i`: Order parameter i (CoupledVar, required) . - * `eta_j`: Order parameter j (CoupledVar, required) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-nucleation.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-nucleation.md deleted file mode 100644 index bb7a91a..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-nucleation.md +++ /dev/null @@ -1,197 +0,0 @@ ---- -id: moose-pf-nucleation -title: MOOSE Nucleation models in MOOSE phase field -domain: phase-field -subdomain: algorithmic -tags: -- discrete-nucleation -- classical-nucleation-theory -- langevin-noise -- nucleation-inserter -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-nucleation-grain-growth - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-nucleation-grain-growth ---- - -# MOOSE Nucleation models in MOOSE phase field - -MOOSE handles phase field nucleation primarily through the `DiscreteNucleation` system, which artificially triggers and stabilizes nuclei formation by modifying the free energy density or directly changing an order parameter . This system involves several components, including `DiscreteNucleationInserter` for managing nucleation sites, `DiscreteNucleationMap` for creating a smooth density map of nuclei, and `DiscreteNucleation` material for applying free energy penalties . - -## Classes & Methods - -* `DiscreteNucleationInserter::validParams()`: Defines the valid input parameters for the `DiscreteNucleationInserter` class . -* `DiscreteNucleationInserter::initialize()`: Clears insertion and deletion counters and expires old nuclei from the local list . -* `DiscreteNucleationInserter::execute()`: Checks each quadrature point for potential nucleation based on a probability density and adds new nuclei . -* `DiscreteNucleationInserter::addNucleus()`: Adds a new nucleus to the local list with its time, center, and radius . -* `DiscreteNucleationMap::validParams()`: Defines the valid input parameters for the `DiscreteNucleationMap` class . -* `DiscreteNucleationMap::execute()`: Rebuilds the spatial map of nucleation sites if required, calculating the distance to the closest nucleus and applying a smooth interface function . -* `DiscreteNucleation::validParams()`: Defines the valid input parameters for the `DiscreteNucleation` material . -* `DiscreteNucleation::computeProperties()`: Calculates the free energy penalty based on the difference between coupled variables and their target concentrations, modified by the nucleus mask from `DiscreteNucleationMap` . -* `DiscreteNucleationData::getValue()`: Returns diagnostic data such as the number of active nuclei, update status, total nucleation rate, or insertion/deletion counts . -* `DiscreteNucleationTimeStep::getValue()`: Provides a time step limit to control the probability of multiple nucleation events within a single time step . - -## Nucleation Algorithm - -### 1. Discrete Nucleation System Overview -The `DiscreteNucleation` system in MOOSE allows for the incorporation of nucleation phenomena in phase field simulations . It addresses the lack of intrinsic nucleation due to thermal fluctuations in phase field methods by artificially triggering and stabilizing nuclei . - -### 2. Nucleation Site Insertion -Nucleation sites are inserted into the phase field using the `DiscreteNucleationInserter` user object . This object manages a global list of active nucleus positions, their insertion times, centers, and radii . During each `execute()` call, it iterates through quadrature points, calculates a nucleation rate based on a material property, and uses a random number to determine if a nucleus should be added . - -` ` `cpp -// From DiscreteNucleationInserter::execute() -for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp) -{ - const Real rate = _probability[qp] * _JxW[qp] * _coord[qp]; // Calculate nucleation rate - _nucleation_rate += rate; - - const Real random = getRandomReal(); - - if (!_time_dep_stats) // Time-independent statistics - { - if (random < rate) - addNucleus(qp); - } - else // Time-dependent statistics - { - if (random < rate * _fe_problem.dt() && random < (1.0 - std::exp(-rate * _fe_problem.dt()))) - addNucleus(qp); - } -} -` ` ` - - -The `addNucleus` method then creates a `NucleusLocation` object with the current time plus a `hold_time`, the quadrature point's coordinates as the center, and a local radius . - -### 3. Classical Nucleation Theory (CNT) Integration: Rate-Based Nucleation -The `DiscreteNucleationInserter` integrates classical nucleation theory by using a `probability` material property, which represents the probability density for inserting a discrete nucleus . This `probability` can be a rate density for time-dependent statistics or a probability density for time-independent statistics . The total nucleation rate is integrated over the domain . - -### 4. Nucleation Seed Representation: Order Parameter Forcing and Smooth Insertion -Nucleation seeds are represented in two main ways: - -* **Free energy penalty based nucleation**: This approach modifies the local free energy density to make the nucleated state a lower energy state, driving solute diffusion or changing a non-conserved order parameter . The `DiscreteNucleation` material implements a harmonic form of this penalty . It calculates a penalty based on the difference between coupled variables (`op_names`) and their `op_values` (target concentrations), scaled by a `penalty` factor and a nucleus mask from `DiscreteNucleationMap` . - - ` ` `cpp - // From DiscreteNucleation::computeProperties() - const std::vector & nucleus = _map.nuclei(_current_elem); // Nucleus mask - for (_qp = 0; _qp < _qrule->n_points(); ++_qp) - { - // ... - const Real penalty = _penalty * nucleus[_qp]; // Modify penalty with nucleus mask - Real dc = (*_args[ii])[_qp] - _op_values[i]; // Deviation from target concentration - // ... - if (_prop_F) - (*_prop_F)[_qp] += dc * dc * penalty; // Build free energy correction - // ... - } - ` ` ` - - -* **Direct order parameter modification**: For non-conserved order parameters, such as in polycrystalline models with `GrainTracker`, direct modification can be used . This involves applying a `DiscreteNucleationForce` and a `Reaction` kernel to a reserved order parameter . - -The `DiscreteNucleationMap` user object creates a smooth density map for nuclei locations . It calculates a `value` for each quadrature point based on its distance `r` to the closest nucleus and a specified `int_width` (interface width) . This allows for smooth insertion of nuclei. - -` ` `cpp -// From DiscreteNucleationMap::execute() -Real value = 0.0; -if (r <= local_radius - _int_width / 2.0) // Inside circle -{ - active_nuclei++; - value = 1.0; -} -else if (r < local_radius + _int_width / 2.0) // Smooth interface -{ - Real int_pos = (r - local_radius + _int_width / 2.0) / _int_width; - active_nuclei++; - value = (1.0 + std::cos(int_pos * libMesh::pi)) / 2.0; -} -` ` ` - - -### 5. Langevin Noise -The provided context mentions `LangevinNoise` as a separate mechanism for fluctuation-based nucleation . However, the `DiscreteNucleation` system itself introduces nucleation artificially and does not intrinsically rely on thermal fluctuations or `LangevinNoise` . - -### 6. Nucleation in Multi-Component Systems: Composition-Dependent Nucleation Barriers -The `DiscreteNucleation` material allows for coupling to multiple variables (`op_names`) and setting target values (`op_values`) for these variables . This enables the definition of composition-dependent nucleation barriers by specifying target concentrations for different components. The free energy penalty is then calculated based on the deviation from these target concentrations . - -### 7. Conservation Issues -The `DiscreteNucleation` system, particularly the free energy penalty approach, "eschews directly modifying conserved concentration and non-conserved order parameter fields" . Instead, it biases the thermodynamics to drive the formation of nuclei . For conserved order parameters, a `DerivativeSumMaterial` is used to add the nucleation free energy penalty to the physical free energy contributions, which are then utilized by a Cahn-Hilliard kernel . This suggests that mass conservation is handled by integrating the nucleation penalty into the existing conservation equations (e.g., Cahn-Hilliard). - -## Relationships - -` ` `mermaid -classDiagram - class DiscreteNucleationInserter { - +addNucleus() - -_probability - -_hold_time - -_local_nucleus_list - -_nucleation_rate - -_local_radius - -_time_dep_stats - } - - class DiscreteNucleationMap { - +nuclei() - -_inserter - -_nucleus_list - -_int_width - -_nucleus_map - } - - class DiscreteNucleation { - +computeProperties() - -_nvar - -_op_index - -_op_values - -_penalty - -_penalty_mode - -_map - } - - class DiscreteNucleationData { - +getValue() - -_inserter - -_nucleus_list - -_value_type - } - - class DiscreteNucleationTimeStep { - +getValue() - -_inserter - -_dt_nucleation - -_changes_made - -_rate - -_max_lambda - } - - DiscreteNucleationInserterBase <|-- DiscreteNucleationInserter - ElementUserObject <|-- DiscreteNucleationMap - DerivativeFunctionMaterialBase <|-- DiscreteNucleation - GeneralPostprocessor <|-- DiscreteNucleationData - GeneralPostprocessor <|-- DiscreteNucleationTimeStep - - DiscreteNucleationMap --> DiscreteNucleationInserter : uses _inserter - DiscreteNucleation --> DiscreteNucleationMap : uses _map - DiscreteNucleationData --> DiscreteNucleationInserterBase : uses _inserter - DiscreteNucleationTimeStep --> DiscreteNucleationInserterBase : uses _inserter -` ` ` - -## Parameters - -### `DiscreteNucleationInserter` -* `probability` (MaterialPropertyName, required): Probability density for inserting a discrete nucleus . -* `hold_time` (Real, required): Duration of time each nucleus is kept active after insertion . -* `radius` (MaterialPropertyName, default: "r_crit"): Variable radius material property name, or a constant value . -* `time - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-solver-strategy.md b/packages/akms/src/akms/_bundled/global_nodes/moose-pf-solver-strategy.md deleted file mode 100644 index f062d6e..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-pf-solver-strategy.md +++ /dev/null @@ -1,216 +0,0 @@ ---- -id: moose-pf-solver-strategy -title: MOOSE Phase field time stepping and preconditioning strategies -domain: phase-field -subdomain: algorithmic -tags: -- time-stepping -- adaptive-dt -- preconditioning -- operator-splitting -- AMR-interface -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-phase-field-numerics - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-phase-field-numerics -- to: tgs-dom-time-integration - type: implements - weight: 0.5 - note: Phase field solver strategies and time adaptivity ---- - -# MOOSE Phase field time stepping and preconditioning strategies - -The MOOSE framework provides extensive capabilities for solving phase field problems, including options for operator splitting, preconditioning, and mesh adaptivity. The `Phase Field Module` supports both Allen-Cahn and Cahn-Hilliard equations, with different solution approaches for the latter. - -## Operator Splitting and Semi-Implicit Schemes - -### Allen-Cahn Equation -The Allen-Cahn equation, which describes non-conserved order parameters, is typically solved directly. The residual equation is split into three kernels: `TimeDerivative`, `ACInterface`, and `AllenCahn` . - -### Cahn-Hilliard Equation -The Cahn-Hilliard equation, which describes conserved order parameters, can be solved in two ways: - -1. **Direct Solution**: This involves solving the fourth-order equation directly . The kernels involved are `TimeDerivative`, `CHInterface`, and `CahnHilliard` . -2. **Split Solution**: This approach splits the fourth-order equation into two second-order equations by introducing a chemical potential variable, $\mu_i$ . This splitting can improve convergence . The kernels used for the split form are `CoupledTimeDerivative`, `SplitCHWRes`, and `SplitCHParsed` . MOOSE supports both "forward" and "reverse" split Cahn-Hilliard problems . - -## Preconditioning for Coupled $\eta + c$ Systems - -MOOSE leverages PETSc for solving nonlinear systems . For coupled systems, effective preconditioning is crucial. - -### Solution Methods -* `NEWTON`: Requires a full and accurate Jacobian. -* `JFNK`: Jacobian-Free Newton-Krylov, does not require Jacobian terms but often needs preconditioning. -* `PJFNK`: Preconditioned JFNK, uses the Jacobian for preconditioning but it doesn't need to be fully correct. - -### Preconditioning Options -* **LU Decomposition**: Most accurate but expensive and does not scale well beyond tens of processors . Useful for debugging. - ` ` `ini - petsc_options_iname = '-pc_type' - petsc_options_value = 'lu' - ` ` ` -* **Additive Schwartz Method (ASM)**: A domain decomposition method that works well for most models, especially with the split Cahn-Hilliard equations . Increasing `-pc_asm_overlap` improves performance at higher computational cost . - ` ` `ini - petsc_options_iname = '-pc_type -ksp_grmres_restart -sub_ksp_type -sub_pc_type -pc_asm_overlap' - petsc_options_value = 'asm 31 preonly lu 2' - ` ` ` -* **ASM/ILU**: Incomplete factorization method, default and works well for elliptic problems . -* **BoomerAMG**: Algebraic MultiGrid Method (Hypre implementation). Works well for Allen-Cahn and direct Cahn-Hilliard, but performs poorly with split Cahn-Hilliard equations . - ` ` `ini - petsc_options_iname = '-pc_type -pc_hypre_type -ksp_gmres_restart -pc_hypre_boomeramg_strong_threshold' - petsc_options_value = 'hypre boomeramg 31 0.7' - ` ` ` - -### Block Structure for Coupled $\eta + c$ Systems -For coupled $\eta + c$ systems, the `FieldSplitPreconditioner` (aliased as `FSP`) is designed to handle block matrices. It allows defining coupling between variables . The `PhysicsBasedPreconditioner` (aliased as `PBP`) also allows individual physics to have their own preconditioners and defines a `solve_order` for block rows . - -## `PhaseFieldSplit` Preconditioner -MOOSE does not have a specific `PhaseFieldSplit` preconditioner class by that exact name. However, the `FieldSplitPreconditioner` and `PhysicsBasedPreconditioner` provide the functionality for physics-based splitting. These allow you to define how different variables (e.g., $\eta$ and $c$) are coupled and preconditioned. The `Split` base class provides options for `splitting_type` such as additive, multiplicative, symmetric multiplicative, and Schur . - -## Convergence Difficulties and Mitigation -Stiffness in phase field problems often arises from the disparate time scales of the physical phenomena or the strong non-linearities. - -* **Operator Splitting**: For Cahn-Hilliard equations, using the split formulation can improve convergence . -* **Preconditioning**: Appropriate PETSc preconditioners are crucial. As mentioned above, `ASM` is recommended for split Cahn-Hilliard equations, while `BoomerAMG` works well for Allen-Cahn and direct Cahn-Hilliard . -* **Time Integration**: Implicit time integration is generally used for phase field models . - -## Mesh Adaptivity for Phase Field -Refining near interfaces and coarsening in the bulk is a common strategy for phase field problems to efficiently resolve sharp interfaces. While the provided context does not explicitly detail specific "indicators" for mesh adaptivity within the phase field module, MOOSE generally supports mesh adaptivity. Typically, indicators would be based on gradients of the order parameter ($\nabla \eta$) or other field variables that define the interface. High gradients would trigger refinement. - -## `InterfaceWidth` or Similar Postprocessor -The provided context does not explicitly mention an `InterfaceWidth` postprocessor. However, MOOSE's modular design allows for the creation of custom postprocessors to monitor various quantities. A postprocessor to monitor interface resolution would likely involve calculating the width of the interface based on the order parameter profile. - -## Solver Configuration Examples - -Here's a typical solver configuration for a multi-phase problem involving coupled Allen-Cahn and split Cahn-Hilliard equations, using `PJFNK` with `ASM` preconditioning, as suggested for split Cahn-Hilliard problems . - -` ` `ini -[Executioner] - type = Transient - solve_type = PJFNK # Preconditioned JFNK - petsc_options_iname = '-pc_type -ksp_grmres_restart -sub_ksp_type -sub_pc_type -pc_asm_overlap' - petsc_options_value = 'asm 31 preonly lu 2' - # Other time stepping parameters - dt = 1e-3 - end_time = 1.0 - nl_abs_tol = 1e-6 - nl_rel_tol = 1e-8 - nl_max_its = 20 - l_max_its = 100 -[] - -[Problem] - type = ReferenceResidualProblem - # Other problem settings -[] - -[Variables] - [./eta] - order = FIRST - family = LAGRANGE - [../] - [./c] - order = FIRST - family = LAGRANGE - [../] - [./mu] # Chemical potential for split Cahn-Hilliard - order = FIRST - family = LAGRANGE - [../] -[] - -[Kernels] - # Allen-Cahn kernels for 'eta' - [./ac_time] - type = TimeDerivative - variable = eta - [../] - [./ac_interface] - type = ACInterface - variable = eta - kappa = kappa_eta_prop - L = L_eta_prop - [../] - [./ac_bulk] - type = AllenCahn - variable = eta - L = L_eta_prop - f_prime = f_prime_eta_prop - [../] - - # Split Cahn-Hilliard kernels for 'c' and 'mu' - [./ch_time] - type = CoupledTimeDerivative - variable = mu # Solves for mu, but time derivative of c - coupled_variable = c - [../] - [./ch_mobility] - type = SplitCHWRes - variable = mu - M = M_c_prop - [../] - [./ch_residual] - type = SplitCHParsed - variable = c - kappa = kappa_c_prop - f_prime = f_prime_c_prop - coupled_variable = mu - [../] -[] - -[Materials] - [./kappa_eta] - type = GenericFunctionMaterial - prop_name = kappa_eta_prop - f_name = '1.0' - [../] - [./L_eta] - type = GenericFunctionMaterial - prop_name = L_eta_prop - f_name = '1.0' - [../] - [./f_prime_eta] - type = GenericFunctionMaterial - prop_name = f_prime_eta_prop - f_name = 'eta^3 - eta' # Example free energy derivative - [../] - [./kappa_c] - type = GenericFunctionMaterial - prop_name = kappa_c_prop - f_name = '1.0' - [../] - [./M_c] - type = GenericFunctionMaterial - prop_name = M_c_prop - f_name = '1.0' - [../] - [./f_prime_c] - type = GenericFunctionMaterial - prop_name = f_prime_c_prop - f_name = 'c^3 - c' # Example free energy derivative - [../] -[] -` ` ` - -## Classes & Methods - -* `FieldSplitPreconditioner::FieldSplitPreconditioner(const InputParameters & params)`: Constructor for the field split preconditioner, sets up the coupling matrix and decomposition split . -* `PhysicsBasedPreconditioner::addSystem(unsigned int var, std::vector off_diag, libMesh::PreconditionerType type)`: Adds a diagonal system and optionally off-diagonal ones, specifying the preconditioning type . -* `Split::setup(NonlinearSystemBase & nl, const std::string & prefix)`: Sets up the split decomposition for a nonlinear system . -* `SplitCHCRes::computeQpResidual()`: Computes the residual for the split Cahn-Hilliard concentration equation . - -## Equations - -### Allen-Cahn Equation (Strong Form) -$$ -\frac{\partial \eta_j}{\partial t} = -L \left( \frac{\partial f_{loc}}{\partial \eta_j} - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-phase-field-mechanics-coupling.md b/packages/akms/src/akms/_bundled/global_nodes/moose-phase-field-mechanics-coupling.md deleted file mode 100644 index ce5d367..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-phase-field-mechanics-coupling.md +++ /dev/null @@ -1,349 +0,0 @@ ---- -id: moose-phase-field-mechanics-coupling -title: MOOSE Phase Field — Solid Mechanics Two-Way Coupling -domain: phase-field -subdomain: algorithmic -tags: -- elastic-energy -- eigenstrain -- two-way-coupling -- microstructural-evolution -- composite-elasticity-tensor -- switching-function -- vegards-law -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-derivative-parsed-material - type: requires - weight: 0.6 - note: Uses DerivativeParsedMaterial for free energy definitions -- to: moose-strain-formulations - type: requires - weight: 0.7 - note: Two-way coupling requires mechanics -- to: moose-allen-cahn-cahn-hilliard - type: requires - weight: 0.6 - note: Elastic energy enters AC driving force -- to: cm-kinematics-tl - type: implements - weight: 0.5 - note: Phase-dependent eigenstrains affect mechanical deformation ---- - -# MOOSE Phase Field — Solid Mechanics Two-Way Coupling - -Framework knowledge node covering 2 aspect(s) of Phase Field — Solid Mechanics Two-Way Coupling. - -## Elastic energy coupling with phase field - -The MOOSE framework couples elastic strain energy with phase field evolution primarily through the `ElasticEnergyMaterial` class, which calculates the elastic free energy and its derivatives, and the `ACGrGrElasticDrivingForce` kernel, which incorporates these elastic energy derivatives into the Allen-Cahn equation. Phase-dependent eigenstrains are handled by classes like `ComputeVariableEigenstrain`, which allows the eigenstrain to be a function of order parameters. This creates a two-way coupling where the phase field influences the elastic strain, and the resulting elastic energy feeds back into the phase field evolution. - -## Elastic Energy Contribution to Total Free Energy -The elastic energy contribution, $f_{elastic} = \frac{1}{2} \epsilon^e : C : \epsilon^e$, is added to the total free energy through the `ElasticEnergyMaterial` class . This material computes the elastic free energy density and its derivatives with respect to coupled variables, which can include phase field order parameters . The `computeF()` method within `ElasticEnergyMaterial` calculates this elastic free energy density . - -## Eigenstrain from Phase Transformation -MOOSE defines phase-dependent eigenstrains using material classes derived from `ComputeEigenstrainBase` . Specifically, `ComputeVariableEigenstrain` is designed to make the eigenstrain a function of multiple variables, such as order parameters . - -## `ComputeVariableEigenstrain` and Order Parameter Dependence -The `ComputeVariableEigenstrain` class makes the eigenstrain a function of the order parameter $\eta$ by taking a `prefactor` material property that depends on the coupled variables (`args`) . The `computeQpEigenstrain()` method calculates the eigenstrain as the product of a base tensor and this prefactor . The derivatives of the eigenstrain with respect to the coupled variables are also computed, which are crucial for the two-way coupling . - -## Two-Way Coupling -The two-way coupling is achieved as follows: -1. **Order parameter affects eigenstrain**: The phase field order parameter ($\eta$) influences the eigenstrain through `ComputeVariableEigenstrain` by acting as one of the `args` for the `prefactor` . -2. **Eigenstrain changes stress**: The eigenstrain contributes to the total strain, which in turn affects the stress and elastic energy calculated by the solid mechanics module. -3. **Elastic energy feeds back to PF driving force**: The `ACGrGrElasticDrivingForce` kernel calculates the portion of the Allen-Cahn equation that results from the deformation energy . This kernel requires the elastic strain and the derivative of the elasticity tensor as material properties . The `computeDFDOP()` method in `ACGrGrElasticDrivingForce` computes this driving force . - -## `ElasticEnergyMaterial` and $\partial f_{elastic}/\partial \eta$ -Yes, `ElasticEnergyMaterial` computes $\partial f_{elastic}/\partial \eta$ for the Allen-Cahn equation. It is a `DerivativeFunctionMaterialBase` and its `computeDF()` method calculates the first derivative of the elastic free energy with respect to a coupled variable (e.g., an order parameter $\eta$) . This derivative is then used by kernels like `ACGrGrElasticDrivingForce` to formulate the Allen-Cahn equation. - -## Khachaturyan's Model (Concentration-dependent or Phase-dependent Lattice Mismatch) -MOOSE implements concentration-dependent or phase-dependent lattice mismatch by allowing the eigenstrain to be a function of other variables, such as concentration or order parameters. This is achieved through classes like `ComputeVariableEigenstrain` or `ComputeVariableBaseEigenStrain` . These materials take a `prefactor` that can be defined as a function of concentration or phase field variables, effectively making the eigenstrain (representing lattice mismatch) dependent on these quantities. - -## Implementation: MultiApp or Single-App -The coupling described is typically implemented within a single MOOSE application using coupled variables. The phase field variables and mechanical variables (displacements) are solved simultaneously within the same application. This is evident from the way material properties and their derivatives are fetched and coupled across different modules (e.g., `PhaseFieldApp` and `SolidMechanicsApp`) within the same input file structure . - -## Coupled PDE System - -The general form of the Allen-Cahn equation for an order parameter $\eta_j$ is given by: -$$ -\frac{\partial \eta_j}{\partial t} = - L_j \frac{\delta F}{\delta \eta_j} \label{eq:AC} \quad (1) -$$ -where $F$ is the total free energy functional. When elastic energy is included, $F$ contains an elastic energy term $E_d$ (or $f_{elastic}$) . The functional derivative $\frac{\delta F}{\delta \eta_j}$ will then include $\frac{\partial E_d}{\partial \eta_j}$ . - -The elastic energy density is $f_{elastic} = \frac{1}{2} \epsilon^e : C : \epsilon^e$, where $\epsilon^e = \epsilon - \epsilon^*$ is the elastic strain, $\epsilon$ is the total strain, and $\epsilon^*$ is the eigenstrain. The total strain $\epsilon$ is derived from the displacement field $u$. The eigenstrain $\epsilon^*$ is a function of the order parameter $\eta$. - -The coupled system involves: -1. **Mechanical Equilibrium Equation**: - $$ - \nabla \cdot \sigma = 0 \quad (2) - $$ - where $\sigma = C : \epsilon^e$ is the stress tensor. -2. **Allen-Cahn Equation for Phase Field Evolution**: - $$ - \frac{\partial \eta}{\partial t} = -L \left( \frac{\partial f_{loc}}{\partial \eta} + \frac{\partial f_{elastic}}{\partial \eta} - \nabla \cdot (\kappa \nabla \eta) \right) \quad (3) - $$ - The term $\frac{\partial f_{elastic}}{\partial \eta}$ is the elastic driving force for phase evolution. - -## Classes & Methods - -* `ElasticEnergyMaterial::computeF()`: Computes the elastic free energy density $f_{elastic} = \frac{1}{2} \sigma : \epsilon^e$. -* `ElasticEnergyMaterial::computeDF(unsigned int i_var)`: Computes the first derivative of the elastic free energy density with respect to a coupled variable (e.g., an order parameter $\eta$). -* `ACGrGrElasticDrivingForce::computeDFDOP(PFFunctionType type)`: Calculates the elastic driving force term $\frac{\partial f_{elastic}}{\partial \eta}$ for the Allen-Cahn equation. -* `ComputeVariableEigenstrain::computeQpEigenstrain()`: Calculates the eigenstrain at each quadrature point, making it a function of coupled variables (e.g., order parameters). -* `ComputeVariableEigenstrain::ComputeVariableEigenstrain()`: Fetches derivatives of the prefactor and builds elastic strain derivatives with respect to coupled variables. - -## Parameters - -* `ElasticEnergyMaterial`: - * `base_name`: `string`, "Material property base name" - * `coupled_variables`: `vector`, "Vector of variable arguments of the free energy function" - * `displacement_gradients`: `vector`, "Vector of displacement gradient variables" -* `ComputeVariableEigenstrain`: - * `args`: `vector`, "variable dependencies for the prefactor" (required) -* `ACGrGrElasticDrivingForce`: - * Inherits parameters from `ACBulk`. - -## Relationships - -` ` `mermaid -classDiagram - direction LR - class Material { - +computeQpProperties() - } - class DerivativeMaterialInterface { - } - class ComputeEigenstrainBase { - +computeQpEigenstrain() - } - class ComputeVariableEigenstrain { - -_num_args - -_dprefactor - -_d2prefactor - -_delastic_strain - -_d2elastic_strain - } - class ElasticEnergyMaterial { - -_stress - -_elasticity_tensor - -_strain - +computeF() - +computeDF() - } - class ACBulk { - +computeDFDOP() - } - class ACGrGrElasticDrivingForce { - -_D_elastic_tensor - -_elastic_strain - } - class AllenCahn { - -_dFdEta - -_d2FdEta2 - -_d2FdEtadarg - } - - Material <|-- ComputeEigenstrainBase - DerivativeMaterialInterface <|-- ComputeVariableEigenstrain - ComputeEigenstrainBase <|-- ComputeVariableEigenstrain - DerivativeFunctionMaterialBase <|-- ElasticEnergyMaterial - ACBulk <|-- ACGrGrElasticDrivingForce - ACBulk <|-- AllenCahn - - ComputeVariableEigenstrain ..> MaterialProperty : "sets _eigenstrain" - ElasticEnergyMaterial ..> MaterialProperty : "gets _stress, _elasticity_tensor, _strain" - ACGrGrElasticDrivingForce ..> MaterialProperty : "gets _D_elastic_tensor, _elastic_strain" - - ElasticEnergyMaterial --|> "calculates ∂f_elastic/∂η" ACGrGrElasticDrivingForce - ComputeVariableEigenstrain --|> "defines ε*(η)" ElasticEnergyMaterial -` ` ` - -## MOOSE Input Syntax - -` ` `ini -[Materials] - [./elastic_tensor] - type = ComputeIsotropicElasticityTensor - block = 0 - youngs_modulus = 100e9 - poissons_ratio = 0.3 - [../] - [./eigenstrain_prefactor] - type = GenericFunctionMaterial - prop_names = 'prefactor' - f_name = 'eta' # Assuming 'eta' is the order parameter variable - block = 0 - [../] - [./eigenstrain] - type = ComputeVariableEigenstrain - block = 0 - eigen_base_tensor = '1 0 0 0 1 0 0 0 1' # Isotropic eigenstrain - prefactor = eigenstrain_prefactor/prefactor - args = eta # Coupled to the order parameter 'eta' - [../] - [./elastic_energy] - type = ElasticEnergyMaterial - block = 0 - coupled_variables = eta # Coupled to the order parameter 'eta' - displacement_gradients = 'disp_x_grad_x disp_x_grad_y disp_x_grad_z disp_y_grad_x disp_y_grad_y disp_y_grad_z disp_z_grad_x disp_z_grad_y disp_z_grad_z' - elasticity_tensor = elastic_tensor/elasticity_tensor - elastic_strain = total_elastic_strain # This is the elastic strain (total - eigen) - [../] -[] - -[Kernels] - [./ac_elastic_driving_force] - type = ACGrGrElasticDrivingForce - variable = eta - block = 0 - elastic_tensor_derivative = elastic_energy/delasticity_tensor_d_eta # Derivative of C w.r.t. eta - elastic_strain = elastic_energy/elastic_strain # Elastic strain - [../] - [./ac_bulk] - type = AllenCahn - variable = eta - block = 0 - f_name = free_energy_material/f_local # Local free energy contribution - [../] -[] - -[Functions] - [./free_energy_function] - type = ParsedFunction - value = 'f_local(eta)' # Define your local free energy function - [../] -[] - -[Problem] - type = Reference - coord_type = XYZ - [./Executioner] - type = Transient - solve_type = 'NEWTON' - [../] -[] - -[Variables] - [./disp_x] - type = Displacement - order = FIRST - family = LAGRANGE - [../] - [./disp_y] - type = Displacement - order = FIRST - family = LAGRANGE - [../] - [./disp_z] - type = Displacement - order = FIRST - family = LAGRANGE - [../] - [./eta] - type = OrderParameter - order = FIRST - - - -## Phase field parameters in constitutive models - -MOOSE integrates phase field variables into solid mechanics constitutive models primarily through material classes that allow for phase-dependent material properties and stress calculations. - -## Phase-dependent elastic moduli: $C(\eta) = h(\eta) \cdot C_{phase1} + (1-h(\eta)) \cdot C_{phase2}$ - -The `ComputeConcentrationDependentElasticityTensor` class is used to define an elasticity tensor that depends on a concentration field, which can represent a phase field variable . This class interpolates between two elasticity tensors, `_Cijkl0` and `_Cijkl1`, based on the value of a coupled concentration variable `_c` . - -### Classes & Methods: -* `ComputeConcentrationDependentElasticityTensor::validParams()`: Defines the input parameters for the concentration-dependent elasticity tensor, including two stiffness tensors (`C0_ijkl`, `C1_ijkl`) and a coupled concentration variable (`c`) . -* `ComputeConcentrationDependentElasticityTensor::computeQpElasticityTensor()`: Computes the elasticity tensor at a given quadrature point using a linear interpolation formula . - -### Equations: -The elasticity tensor $C$ is computed as: -$$ -C = C_{ijkl0} + (C_{ijkl1} - C_{ijkl0}) \cdot c \quad (1) -$$ -where $C_{ijkl0}$ is the stiffness tensor for zero concentration, $C_{ijkl1}$ is the stiffness tensor for concentration 1.0, and $c$ is the concentration variable . - -## `CompositeElasticityTensor` — how does it interpolate tensors between phases? - -The `CompositeElasticityTensor` class is used to combine multiple elasticity tensors with corresponding weights . While the provided snippets do not show its C++ implementation, an example input file demonstrates its usage where `tensors` are combined with `weights` . This allows for interpolation of elasticity tensors based on material properties that can be derived from phase field variables. - -## Creep/plasticity parameters that depend on phase - -MOOSE supports phase-dependent creep and plasticity parameters. The test suite for `CompositePowerLawCreepStressUpdate` indicates that the system provides phase-dependent power law creep that can handle different material properties for different phases . This includes scenarios with multiple plasticity rules for different phases . The input parameters for such creep models, like activation energy, coefficient, and n-exponent, are expected to have lengths equal to the number of switching functions (phases) . - -## Swelling eigenstrains: coupling species concentration c to volumetric strain - -The `ElasticEnergyMaterial` class is designed to handle elastic energy contributions and can fetch stress and elasticity tensor derivatives with respect to coupled variables . This framework allows for coupling species concentration `c` to volumetric strain by defining the elastic strain and elasticity tensor as functions of `c` and their derivatives. - -## Thermal expansion differences between phases: phase-dependent CTE - -While not explicitly shown in the provided snippets, the general approach for phase-dependent material properties in MOOSE, as demonstrated with elasticity tensors and creep parameters, would extend to thermal expansion coefficients. A material class similar to `ComputeConcentrationDependentElasticityTensor` could be implemented to interpolate CTE values based on a phase field variable. - -## How to ensure thermodynamic consistency when mixing phase field and mechanics? - -Thermodynamic consistency in coupled phase field and mechanics problems is ensured by defining a global free energy functional that includes contributions from both the local free energy density ($f_{loc}$), gradient energy density ($f_{gr}$), and additional energy sources like deformation energy ($E_d$) . The evolution equations for phase field variables (conserved and non-conserved) are derived from the functional derivatives of this global free energy . - -For two-phase models, the `DerivativeTwoPhaseMaterial` combines phase free energies into a global free energy using a switching function $h(\eta)$ . -$$ -F = (1-h(\eta)) F_a + h(\eta)F_b + Wg(\eta) \quad (2) -$$ -where $F_a$ and $F_b$ are the free energies of phase A and B, respectively, and $\eta$ is the order parameter. The `TwoPhaseStressMaterial` and `MultiPhaseStressMaterial` classes calculate global stress and its derivative with respect to strain by interpolating between phase-specific stresses and stiffnesses using a switching function `_h_eta` . This approach ensures that the mechanical response is consistent with the phase distribution. - -### Classes & Methods: -* `TwoPhaseStressMaterial::computeQpProperties()`: Computes the global stress and its Jacobian by linearly interpolating between the stresses and Jacobians of two phases using a switching function `_h_eta` . -* `ElasticEnergyMaterial`: A free energy material for elastic energy contributions, which can be coupled with other variables like concentration . - -### MOOSE Input Syntax: -For phase-dependent elastic moduli using `ComputeConcentrationDependentElasticityTensor`: -` ` `ini -[Materials] - [./elasticity_tensor] - type = ComputeConcentrationDependentElasticityTensor - block = '1' - C0_ijkl = '...' # Stiffness tensor for zero concentration phase - C1_ijkl = '...' # Stiffness tensor for concentration 1.0 phase - c = concentration_variable # Coupled concentration variable - [../] -[] -` ` ` - -For combining stresses from multiple phases using `TwoPhaseStressMaterial`: -` ` `ini -[Materials] - [./phase_A_stress] - type = SomeElasticStressMaterial - block = '1' - # ... parameters for phase A stress - [../] - [./phase_B_stress] - type = SomeElasticStressMaterial - block = '1' - # ... parameters for phase B stress - [../] - [./switching_function] - type = SwitchingFunctionMaterial - block = '1' - # ... parameters for h(eta) - [../] - [./global_stress] - type = TwoPhaseStressMaterial - block = '1' - h = switching_function # Material property providing h(eta) - base_A = phase_A_stress # Base name for Phase A strain/stress - base_B = phase_B_stress # Base name for Phase B strain/stress - [../] -[] -` ` ` - -## Notes -The provided context primarily focuses on elastic properties and general free energy formulations. Specific implementations for phase-dependent thermal expansion coefficients (CTE) were not directly found, but the framework suggests that similar material classes could be developed. The `ComputePolycrystalElasticityTensor` class also deals with evolving elasticity tensors coupled to grain growth phase field models, which is a related concept but not directly addressing the user's specific question about $C(\eta) = h(\eta) \cdot C_{phase1} + (1-h(\eta)) \cdot C_{phase2}$ . - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-phase-field-numerics.md b/packages/akms/src/akms/_bundled/global_nodes/moose-phase-field-numerics.md deleted file mode 100644 index 47459f8..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-phase-field-numerics.md +++ /dev/null @@ -1,300 +0,0 @@ ---- -id: moose-phase-field-numerics -title: MOOSE Phase Field Constraints and Numerical Techniques -domain: phase-field -subdomain: algorithmic -tags: -- constraints -- mass-conservation -- time-stepping -- nucleation -- adaptive-dt -- stabilization -- interface-width -- BDF2 -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-derivative-parsed-material - type: requires - weight: 0.6 - note: Uses DerivativeParsedMaterial for free energy definitions -- to: moose-allen-cahn-cahn-hilliard - type: requires - weight: 0.7 - note: Numerical techniques applied to AC/CH solves -- to: moose-jfnk-preconditioning - type: requires - weight: 0.5 - note: Phase field preconditioning uses JFNK infrastructure -- to: tgs-dom-time-integration - type: implements - weight: 0.5 - note: Phase field time integration strategies ---- - -# MOOSE Phase Field Constraints and Numerical Techniques - -Framework knowledge node covering 2 aspect(s) of Phase Field Constraints and Numerical Techniques. - -## Constraint enforcement and numerical stabilization - -MOOSE employs various numerical techniques for phase field simulations, including specific approaches for nucleation events and time step adaptivity. The framework provides kernels for solving both Allen-Cahn and Cahn-Hilliard equations, allowing for different solution strategies. - -## Phase Field Nucleation -MOOSE handles nucleation events through a `DiscreteNucleation` system . This system artificially triggers and stabilizes nuclei formation by locally modifying the free energy density or directly changing an order parameter . - -### Classes & Methods -* `DiscreteNucleationInserter`: A user object that manages a global list of active nucleus positions . -* `DiscreteNucleationMap`: A user object that maintains a smooth density map for nuclei locations, obtained from a `DiscreteNucleationInserter` . -* `DiscreteNucleation`: A material that calculates a local free energy penalty based on the difference between concentration variables and their target concentrations . -* `DiscreteNucleationTimeStep`: A postprocessor that provides a time step limit for new nuclei, used with `IterationAdaptiveDT` . - -### Parameters -* `DiscreteNucleation::penalty`: `Real`, default `20.0`. Penalty factor for enforcing target concentrations . -* `DiscreteNucleation::penalty_mode`: `MooseEnum`, default `MATCH`. Determines if the target concentration is matched, or taken as a minimum or maximum . -* `DiscreteNucleationTimeStep::dt_max`: `Real`. Time step to cut back to at the start of a nucleation event . -* `DiscreteNucleationTimeStep::p2nucleus`: `Real`, range `(0, 1)`. Maximum probability for more than one nucleus to appear during a time step . - -### Free Energy Penalty Based Nucleation -The `DiscreteNucleation` material implements a harmonic form of a free energy penalty to bias the system's thermodynamics, driving the formation of nuclei . - -### Direct Order Parameter Modification -For non-conserved order parameters, direct modification can be achieved by applying a `DiscreteNucleationForce` and a `Reaction` kernel to a reserved order parameter . - -## Time Integration Schemes -MOOSE's `Transient` executioner allows for time-dependent simulations . The `scheme` parameter in the `Executioner` block determines the `TimeIntegrator` to use . While the documentation mentions Backward Euler as a default , it also supports other schemes like BDF2 . - -## Time Step Adaptivity -Time step adaptivity is supported through objects like `DiscreteNucleationTimeStep` and `IterationAdaptiveDT` . The `DiscreteNucleationTimeStep` postprocessor limits the time step based on two criteria: a user-defined `dt_max` at nucleus insertion and a nucleation rate-based limit to control the probability of multiple nucleation events within a single time step . - -### Equations -The probability of more than two nucleation events ($p_{2nuc}$) is calculated as: -$$ -p_{2nuc} = 1-(1+\lambda_{2nuc})e^{-\lambda_{2nuc}} \label{eq:p2nuc} \tag{1} -$$ -where $\lambda_{2nuc}$ is the total nucleation rate over the simulation cell . This equation is numerically inverted to obtain $\lambda_{2nuc}$ for a given $p_{2nuc}$ . - -## Mass Conservation for Cahn-Hilliard -The Cahn-Hilliard equation, which describes mass conservation, can be solved in two ways within MOOSE . -1. **Direct solution of the fourth-order equation**: This involves solving the equation directly . -2. **Split into two second-order equations**: This approach solves for concentration ($c_i$) and chemical potential ($\mu_i$) separately . This method is noted to improve solve convergence . - -### Equations -The residual for the direct solution of the Cahn-Hilliard equation is: -$$ -\boldsymbol{\mathcal{R}}_{c_i} = \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( \kappa_i \nabla^2 c_i, \nabla \cdot (M_i \nabla \psi_m ) \right) + \left( M_i \left( \nabla \frac{\partial f_{loc} }{\partial c_i} + \nabla \frac{\partial E_d}{\partial c_i} \right), \nabla \psi_m \right) \label{eq:ch_direct_residual} \tag{2} -$$ -For the split form, the two residual equations are: -$$ -\begin{aligned} - \boldsymbol{\mathcal{R}}_{\mu_i} &=& \left( \frac{\partial c_i}{\partial t}, \psi_m \right) + \left( M_i \nabla \mu_i, \nabla \psi_m \right) \\ - \boldsymbol{\mathcal{R}}_{c_i} &=& \left( \left( -\kappa_i \nabla^2 c_i + \frac{\partial f_{loc}}{\partial c_i} + \frac{\partial E_d}{\partial c_i} - \mu_i \right), \psi_m \right) -\end{aligned} \label{eq:ch_split_residual} \tag{3} -$$ - -## Order Parameter Constraint $\Sigma\eta_i = 1$ -The provided context does not explicitly detail the numerical techniques used for enforcing the order parameter constraint $\Sigma\eta_i = 1$, such as penalty methods, Lagrange multipliers, or variable elimination. - -## Numerical Stabilization -The provided context does not explicitly mention numerical stabilization techniques like anti-trapping currents for sharp-interface limits. - -## Interface Width Control -The provided context does not explicitly detail the relationship between $\kappa$, interface width ($W$), and mesh size requirements. However, the `DiscreteNucleationMap` user object has an `int_width` parameter for the nucleus interface width . - -## Notes -The MOOSE phase field module is designed to simplify the implementation of phase field models by leveraging common structures like the Cahn-Hilliard and Allen-Cahn equations and free energy functionals . The framework uses PETSc for solving nonlinear equations and offers different solution methods like `NEWTON`, `JFNK`, and `PJFNK` . Preconditioning options such as LU decomposition and Additive Schwartz Method (ASM) are available to improve performance . - - -## Phase field time stepping and preconditioning strategies - -The MOOSE framework provides extensive capabilities for solving phase field problems, including options for operator splitting, preconditioning, and mesh adaptivity. The `Phase Field Module` supports both Allen-Cahn and Cahn-Hilliard equations, with different solution approaches for the latter. - -## Operator Splitting and Semi-Implicit Schemes - -### Allen-Cahn Equation -The Allen-Cahn equation, which describes non-conserved order parameters, is typically solved directly. The residual equation is split into three kernels: `TimeDerivative`, `ACInterface`, and `AllenCahn` . - -### Cahn-Hilliard Equation -The Cahn-Hilliard equation, which describes conserved order parameters, can be solved in two ways: - -1. **Direct Solution**: This involves solving the fourth-order equation directly . The kernels involved are `TimeDerivative`, `CHInterface`, and `CahnHilliard` . -2. **Split Solution**: This approach splits the fourth-order equation into two second-order equations by introducing a chemical potential variable, $\mu_i$ . This splitting can improve convergence . The kernels used for the split form are `CoupledTimeDerivative`, `SplitCHWRes`, and `SplitCHParsed` . MOOSE supports both "forward" and "reverse" split Cahn-Hilliard problems . - -## Preconditioning for Coupled $\eta + c$ Systems - -MOOSE leverages PETSc for solving nonlinear systems . For coupled systems, effective preconditioning is crucial. - -### Solution Methods -* `NEWTON`: Requires a full and accurate Jacobian. -* `JFNK`: Jacobian-Free Newton-Krylov, does not require Jacobian terms but often needs preconditioning. -* `PJFNK`: Preconditioned JFNK, uses the Jacobian for preconditioning but it doesn't need to be fully correct. - -### Preconditioning Options -* **LU Decomposition**: Most accurate but expensive and does not scale well beyond tens of processors . Useful for debugging. - ` ` `ini - petsc_options_iname = '-pc_type' - petsc_options_value = 'lu' - ` ` ` -* **Additive Schwartz Method (ASM)**: A domain decomposition method that works well for most models, especially with the split Cahn-Hilliard equations . Increasing `-pc_asm_overlap` improves performance at higher computational cost . - ` ` `ini - petsc_options_iname = '-pc_type -ksp_grmres_restart -sub_ksp_type -sub_pc_type -pc_asm_overlap' - petsc_options_value = 'asm 31 preonly lu 2' - ` ` ` -* **ASM/ILU**: Incomplete factorization method, default and works well for elliptic problems . -* **BoomerAMG**: Algebraic MultiGrid Method (Hypre implementation). Works well for Allen-Cahn and direct Cahn-Hilliard, but performs poorly with split Cahn-Hilliard equations . - ` ` `ini - petsc_options_iname = '-pc_type -pc_hypre_type -ksp_gmres_restart -pc_hypre_boomeramg_strong_threshold' - petsc_options_value = 'hypre boomeramg 31 0.7' - ` ` ` - -### Block Structure for Coupled $\eta + c$ Systems -For coupled $\eta + c$ systems, the `FieldSplitPreconditioner` (aliased as `FSP`) is designed to handle block matrices. It allows defining coupling between variables . The `PhysicsBasedPreconditioner` (aliased as `PBP`) also allows individual physics to have their own preconditioners and defines a `solve_order` for block rows . - -## `PhaseFieldSplit` Preconditioner -MOOSE does not have a specific `PhaseFieldSplit` preconditioner class by that exact name. However, the `FieldSplitPreconditioner` and `PhysicsBasedPreconditioner` provide the functionality for physics-based splitting. These allow you to define how different variables (e.g., $\eta$ and $c$) are coupled and preconditioned. The `Split` base class provides options for `splitting_type` such as additive, multiplicative, symmetric multiplicative, and Schur . - -## Convergence Difficulties and Mitigation -Stiffness in phase field problems often arises from the disparate time scales of the physical phenomena or the strong non-linearities. - -* **Operator Splitting**: For Cahn-Hilliard equations, using the split formulation can improve convergence . -* **Preconditioning**: Appropriate PETSc preconditioners are crucial. As mentioned above, `ASM` is recommended for split Cahn-Hilliard equations, while `BoomerAMG` works well for Allen-Cahn and direct Cahn-Hilliard . -* **Time Integration**: Implicit time integration is generally used for phase field models . - -## Mesh Adaptivity for Phase Field -Refining near interfaces and coarsening in the bulk is a common strategy for phase field problems to efficiently resolve sharp interfaces. While the provided context does not explicitly detail specific "indicators" for mesh adaptivity within the phase field module, MOOSE generally supports mesh adaptivity. Typically, indicators would be based on gradients of the order parameter ($\nabla \eta$) or other field variables that define the interface. High gradients would trigger refinement. - -## `InterfaceWidth` or Similar Postprocessor -The provided context does not explicitly mention an `InterfaceWidth` postprocessor. However, MOOSE's modular design allows for the creation of custom postprocessors to monitor various quantities. A postprocessor to monitor interface resolution would likely involve calculating the width of the interface based on the order parameter profile. - -## Solver Configuration Examples - -Here's a typical solver configuration for a multi-phase problem involving coupled Allen-Cahn and split Cahn-Hilliard equations, using `PJFNK` with `ASM` preconditioning, as suggested for split Cahn-Hilliard problems . - -` ` `ini -[Executioner] - type = Transient - solve_type = PJFNK # Preconditioned JFNK - petsc_options_iname = '-pc_type -ksp_grmres_restart -sub_ksp_type -sub_pc_type -pc_asm_overlap' - petsc_options_value = 'asm 31 preonly lu 2' - # Other time stepping parameters - dt = 1e-3 - end_time = 1.0 - nl_abs_tol = 1e-6 - nl_rel_tol = 1e-8 - nl_max_its = 20 - l_max_its = 100 -[] - -[Problem] - type = ReferenceResidualProblem - # Other problem settings -[] - -[Variables] - [./eta] - order = FIRST - family = LAGRANGE - [../] - [./c] - order = FIRST - family = LAGRANGE - [../] - [./mu] # Chemical potential for split Cahn-Hilliard - order = FIRST - family = LAGRANGE - [../] -[] - -[Kernels] - # Allen-Cahn kernels for 'eta' - [./ac_time] - type = TimeDerivative - variable = eta - [../] - [./ac_interface] - type = ACInterface - variable = eta - kappa = kappa_eta_prop - L = L_eta_prop - [../] - [./ac_bulk] - type = AllenCahn - variable = eta - L = L_eta_prop - f_prime = f_prime_eta_prop - [../] - - # Split Cahn-Hilliard kernels for 'c' and 'mu' - [./ch_time] - type = CoupledTimeDerivative - variable = mu # Solves for mu, but time derivative of c - coupled_variable = c - [../] - [./ch_mobility] - type = SplitCHWRes - variable = mu - M = M_c_prop - [../] - [./ch_residual] - type = SplitCHParsed - variable = c - kappa = kappa_c_prop - f_prime = f_prime_c_prop - coupled_variable = mu - [../] -[] - -[Materials] - [./kappa_eta] - type = GenericFunctionMaterial - prop_name = kappa_eta_prop - f_name = '1.0' - [../] - [./L_eta] - type = GenericFunctionMaterial - prop_name = L_eta_prop - f_name = '1.0' - [../] - [./f_prime_eta] - type = GenericFunctionMaterial - prop_name = f_prime_eta_prop - f_name = 'eta^3 - eta' # Example free energy derivative - [../] - [./kappa_c] - type = GenericFunctionMaterial - prop_name = kappa_c_prop - f_name = '1.0' - [../] - [./M_c] - type = GenericFunctionMaterial - prop_name = M_c_prop - f_name = '1.0' - [../] - [./f_prime_c] - type = GenericFunctionMaterial - prop_name = f_prime_c_prop - f_name = 'c^3 - c' # Example free energy derivative - [../] -[] -` ` ` - -## Classes & Methods - -* `FieldSplitPreconditioner::FieldSplitPreconditioner(const InputParameters & params)`: Constructor for the field split preconditioner, sets up the coupling matrix and decomposition split . -* `PhysicsBasedPreconditioner::addSystem(unsigned int var, std::vector off_diag, libMesh::PreconditionerType type)`: Adds a diagonal system and optionally off-diagonal ones, specifying the preconditioning type . -* `Split::setup(NonlinearSystemBase & nl, const std::string & prefix)`: Sets up the split decomposition for a nonlinear system . -* `SplitCHCRes::computeQpResidual()`: Computes the residual for the split Cahn-Hilliard concentration equation . - -## Equations - -### Allen-Cahn Equation (Strong Form) -$$ -\frac{\partial \eta_j}{\partial t} = -L \left( \frac{\partial f_{loc}}{\partial \eta_j} - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-preconditioning.md b/packages/akms/src/akms/_bundled/global_nodes/moose-preconditioning.md deleted file mode 100644 index d658a24..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-preconditioning.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -id: moose-preconditioning -title: MOOSE Preconditioning strategies in MOOSE -domain: solver -subdomain: algorithmic -tags: -- SMP -- FDP -- PBP -- AMG -- HYPRE -- block-diagonal -- automatic-differentiation -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-jfnk-preconditioning - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-jfnk-preconditioning ---- - -# MOOSE Preconditioning strategies in MOOSE - -MOOSE provides several preconditioning strategies to enhance the efficiency of solving nonlinear systems, including Single Matrix Preconditioner (SMP), Finite Difference Preconditioner (FDP), and Physics-Based Preconditioner (PBP) . These strategies can be configured within the `[Preconditioning]` block in the input file or through PETSc options . - -## Preconditioning Strategies - -### 1. Single Matrix Preconditioner (SMP) -The `SingleMatrixPreconditioner` builds a preconditioner using user-defined off-diagonal parts of the Jacobian . By default, for `PJFNK` solves, a block-diagonal preconditioning matrix is used where each block corresponds to a single MOOSE variable, ignoring off-diagonal Jacobian terms . You can specify off-diagonal entries using `off_diag_row` and `off_diag_column` parameters, or group variables using `coupled_groups` to generate off-diagonal Jacobians for all pairs within a group . - -**Classes & Methods:** -* `SingleMatrixPreconditioner::SingleMatrixPreconditioner(const InputParameters & params)`: Constructor that sets up the coupling matrix based on input parameters . -* `SingleMatrixPreconditioner::validParams()`: Defines valid input parameters for SMP, including `coupled_groups`, `off_diag_row`, `off_diag_column`, and `full` . - -**MOOSE Input Syntax:** -` ` `ini -[Preconditioning] - [my_smp] - type = SMP - # Example for coupled_groups - coupled_groups = 'var1,var2 var3,var4' - # Example for off_diag_row and off_diag_column - off_diag_row = 'var1 var2' - off_diag_column = 'var2 var1' - [] -[] -` ` ` - -### 2. Finite Difference Preconditioner (FDP) -The `FiniteDifferencePreconditioner` builds a numerical Jacobian for preconditioning by finite differencing . This method is generally costly and is recommended primarily for testing and verification purposes . It can use either a "standard" finite difference approach or one based on "coloring" . The "standard" finite difference method will add off-diagonal entries to the coupling matrix . - -**Classes & Methods:** -* `FiniteDifferencePreconditioner::FiniteDifferencePreconditioner(const InputParameters & params)`: Constructor that initializes the finite difference type . -* `FiniteDifferencePreconditioner::validParams()`: Defines valid input parameters, including `implicit_geometric_coupling` and `finite_difference_type` . - -**Parameters:** -* `finite_difference_type = "standard" | "coloring"` (type: `MooseEnum`, default: `"coloring"`): Specifies the finite differencing method . - -### 3. Physics-Based Preconditioner (PBP) -The `PhysicsBasedPreconditioner` allows individual physics (variables) to have their own preconditioners . It decomposes the system into smaller linear systems, each corresponding to a variable, and applies a specified preconditioner to each . The order in which these block rows are solved can be specified using `solve_order` . Off-diagonal coupling terms can also be included . PBP must be used with the `JFNK` solve type . - -**Classes & Methods:** -* `PhysicsBasedPreconditioner::PhysicsBasedPreconditioner(const InputParameters & params)`: Constructor that sets up the coupling matrix, preconditioner types, and solve order . -* `PhysicsBasedPreconditioner::addSystem(unsigned int var, std::vector off_diag, libMesh::PreconditionerType type)`: Adds a diagonal system and optionally off-diagonal systems, specifying the type of preconditioning for that system . -* `PhysicsBasedPreconditioner::setup()`: Fills in the preconditioning matrix by computing Jacobian blocks for diagonal and specified off-diagonal terms . -* `PhysicsBasedPreconditioner::apply(const NumericVector & x, NumericVector & y)`: Computes the preconditioned vector by solving the individual systems in the specified order, accounting for off-diagonal couplings . - -**MOOSE Input Syntax:** -` ` `ini -[Preconditioning] - [my_pbp] - type = PBP - solve_order = 'temp pressure' # Example: solve temperature then pressure - preconditioner = 'hypre hypre' # Example: use hypre for both - off_diag_row = 'temp' - off_diag_column = 'pressure' - [] -[] -` ` ` - -### 4. Block Diagonal vs. Block Off-Diagonal Coupling -MOOSE determines coupling between variables through a `CouplingMatrix` . -* **Block Diagonal:** By default, for `PJFNK` solves, the preconditioning matrix is block-diagonal, meaning off-diagonal Jacobian terms are ignored . This is represented by setting 1s on the diagonal of the `CouplingMatrix` and 0s elsewhere . -* **Block Off-Diagonal:** You can explicitly include off-diagonal coupling terms using parameters like `off_diag_row` and `off_diag_column` . These parameters specify which variable pairs should have their Jacobian blocks included in the preconditioning matrix . The `full = true` parameter can be used to include all possible couplings between variables for convenience . - -### 5. Algebraic Multigrid (AMG) with HYPRE BoomerAMG -MOOSE leverages PETSc for solvers and preconditioners, including HYPRE's BoomerAMG . BoomerAMG is an algebraic multigrid method suitable for elliptic PDEs . - -**Configuration through MOOSE:** -You configure HYPRE BoomerAMG using PETSc options, which can be set in the `Executioner` or `Preconditioning` blocks using `petsc_options_iname` and `petsc_options_value` . - -**Parameters:** -* `petsc_options_iname = '-pc_type -pc_hypre_type'` -* `petsc_options_value = 'hypre boomeramg'` - -Key BoomerAMG options include: -* `-pc_hypre_boomeramg_strong_threshold`: Controls the coarsening mechanism by setting a threshold for matrix entries to be kept . Default is 0.25, but 0.7 is automatically set for 3D problems . -* `-pc_hypre_boomeramg_max_levels`: Number of multigrid levels . -* `-pc_hypre_boomeramg_coarsen_type`: Coarsening algorithm, e.g., `Falgout` (default), `HMIS`, or `PMIS` . -* `-pc_hypre_boomeramg_agg_nl`: Number of levels for aggressive coarsening . -* `-pc_hypre_boomeramg_agg_num_paths`: Number of pathways to consider for aggressive coarsening . -* `-pc_hypre_boomeramg_truncfactor`: Truncation factor for interpolation . -* `-pc_hypre_boomeramg_interp_type`: Type of interpolation, e.g., `classic` (default) or `ext+i` . - -**MOOSE Input Syntax:** -` ` `ini -[Executioner] - type = Steady - petsc_options_iname = '-pc_type -pc_hypre_type -pc_hypre_boomeramg_strong_threshold' - petsc_options_value = 'hypre boomeramg 0.7' -[] -` ` ` - -### 6. Automatic Differentiation (AD) and Preconditioning -MOOSE uses forward mode automatic differentiation from the MetaPhysicL package to compute Jacobians . When `ADKernel` is used, the Jacobian is automatically calculated . While AD Jacobians can be slower to compute than hand-coded ones, they parallelize well and can benefit from a `NEWTON` solve type, potentially leading to decreased overall solve time . - -The preconditioner is seldom the exact Jacobian because computing it is computationally expensive and memory-intensive . Even with AD, the preconditioner is an approximation of the Jacobian, not necessarily exact . The `PJFNK` solve type uses a preconditioning matrix that approximates the Jacobian . If the Jacobian is not exact, the Newton update might not effectively reduce the residual, potentially leading to unconverged iterations . - -## Notes -The `FieldSplitPreconditioner` (FSP) is another preconditioner that allows custom preconditioning for each nonlinear variable . It can be used for block-diagonal preconditioning and is the default for `PJFNK` solves . While similar in concept to PBP, FSP is a separate implementation. - -Other preconditioners mentioned in the codebase include `MooseStaticCondensationPreconditioner` and `VariableCondensationPreconditioner` . These are specialized preconditioners for static and variable condensation, respectively. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-push-pull-operations.md b/packages/akms/src/akms/_bundled/global_nodes/moose-push-pull-operations.md deleted file mode 100644 index a3e6061..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-push-pull-operations.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -id: moose-push-pull-operations -title: MOOSE Push-forward and pull-back tensor operations -domain: constitutive -subdomain: algorithmic -tags: -- push-forward -- pull-back -- rank-two-tensor -- rank-four-tensor -- piola-transform -- nanson -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-objectivity-frame-operations - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-objectivity-frame-operations -- to: cm-tensor-calculus - type: implements - weight: 0.8 - note: Tensor push-forward/pull-back operations ---- - -# MOOSE Push-forward and pull-back tensor operations - -MOOSE implements push-forward and pull-back operations for tensor quantities, particularly stress and elasticity tensors, within its solid mechanics module for finite deformation analysis. These operations are primarily handled by specialized material classes that manage the transformation between different stress measures (Cauchy, 1st PK, 2nd PK) and their corresponding Jacobians. The `RankTwoTensor` and `RankFourTensor` classes provide fundamental tensor operations, but explicit `pushForward()` or `pullBack()` methods are not directly exposed at that level for general use; instead, these transformations are embedded within the material constitutive models. - -## Classes & Methods - -* `ComputeLagrangianStressCauchy::computeQpPK1Stress()`: Computes the 1st Piola-Kirchhoff stress from Cauchy stress and its Jacobian. -* `ComputeLagrangianStressPK1::computeQpCauchyStress()`: Computes the Cauchy stress from 1st Piola-Kirchhoff stress and its Jacobian. -* `ComputeLagrangianStressPK2::computeQpPK1Stress()`: Computes the 1st Piola-Kirchhoff stress from 2nd Piola-Kirchhoff stress and its Jacobian. -* `ComputeDeformGradBasedStress::computeQpStress()`: Computes Cauchy stress from 2nd PK stress using the deformation gradient. -* `ComputeHypoelasticStVenantKirchhoffStress::computeQpSmallStress()`: Performs push-forward of the elasticity tensor for large kinematics. -* `ComputeLagrangianObjectiveStress::objectiveUpdateTruesdell()`: Implements the Truesdell objective update for Cauchy stress and its Jacobian. -* `ComputeLagrangianObjectiveStress::polarDecomposition()`: Computes polar decomposition of the deformation gradient to get rotation and stretch tensors, and their derivatives. -* `CZMComputeGlobalTractionTotalLagrangian::computeEquilibriumTracionAndDerivatives()`: Computes the 1st Piola-Kirchhoff traction and its derivatives, including the area ratio. - -## Equations - -### 1. Pull-back of Cauchy stress to 2nd PK -The pull-back of Cauchy stress ($\sigma$) to 2nd Piola-Kirchhoff stress ($S$) is implicitly handled by the inverse transformation of the push-forward operation. While not directly expressed as $S = J \cdot F^{-1} \cdot \sigma \cdot F^{-T}$, the MOOSE framework typically computes stresses in a specific configuration and then transforms them as needed. For instance, `ComputeLagrangianStressPK2` is designed to provide the 2nd PK stress and its tangent, and then wraps this to provide the 1st PK stress. - -### 2. Push-forward of 2nd PK to Cauchy -The push-forward of 2nd Piola-Kirchhoff stress ($S$) to Cauchy stress ($\sigma$) is computed in `ComputeDeformGradBasedStress::computeQpStress()` and `ComputeLagrangianStressPK1::computeQpCauchyStress()` . - -$$ -\sigma = \frac{1}{J} \cdot F \cdot S \cdot F^T \quad (1) -$$ - -### 4. Elasticity tensor transformation -The 4th-order push-forward of the elasticity tensor from the reference to the current configuration is implemented in `ComputeHypoelasticStVenantKirchhoffStress::computeQpSmallStress()` . - -$$ -C_{spatial} = \frac{1}{J} \cdot F_{i\alpha} F_{j\beta} F_{k\gamma} F_{l\delta} \cdot C_{ref_{\alpha\beta\gamma\delta}} \quad (2) -$$ -This is represented in code as: -` ` `cpp - const RankTwoTensor F = _def_grad[_qp]; - const Real J = F.det(); - const RankFourTensor FF = F.times(F); - const RankFourTensor FtFt = F.times(F); - const RankFourTensor C0 = _elasticity_tensor[_qp]; - const RankFourTensor C = FF * C0 * FtFt / J; -` ` ` - -### 6. Piola transform for traction (Nanson's formula) -Nanson's formula is explicitly used in `CZMComputeGlobalTractionTotalLagrangian::computeEquilibriumTracionAndDerivatives()` to compute the area ratio for the 1st Piola-Kirchhoff traction. -The area ratio is calculated as: -$$ -\frac{da}{dA} = J \cdot ||F^T N|| \quad (3) -$$ -This is implemented using `CohesiveZoneModelTools::computeAreaRatio` . The 1st Piola-Kirchhoff traction is then computed as $T = \frac{da}{dA} Q \hat{t}$ , where $Q$ is the total rotation and $\hat{t}$ is the interface traction. - -## Algorithm Steps - -### Push-forward of 2nd PK to Cauchy Stress -` ` `pseudocode -function computeQpStress() - iden = RankTwoTensor::Identity() - ee = 0.5 * (_deformation_gradient.transpose() * _deformation_gradient - iden) - pk2 = _elasticity_tensor * ee - _stress = _deformation_gradient * pk2 * _deformation_gradient.transpose() / _deformation_gradient.det() - _Jacobian_mult = _elasticity_tensor -end function -` ` ` - -## Relationships - -` ` `mermaid -classDiagram - class Material { - +initQpStatefulProperties() - +computeQpProperties() - } - class ComputeLagrangianStressBase { - +computeQpStressUpdate() - #_large_kinematics - #_cauchy_stress - #_cauchy_jacobian - #_pk1_stress - #_pk1_jacobian - } - class ComputeLagrangianStressCauchy { - +computeQpCauchyStress() - -computeQpPK1Stress() - #_inv_df - #_inv_def_grad - #_F - } - class ComputeLagrangianStressPK1 { - +computeQpPK1Stress() - -computeQpCauchyStress() - #_inv_df - #_F - } - class ComputeLagrangianStressPK2 { - +computeQpPK2Stress() - #_E - #_S - #_C - } - class ComputeLagrangianObjectiveStress { - +computeQpSmallStress() - -objectiveUpdateTruesdell() - -objectiveUpdateJaumann() - -objectiveUpdateGreenNaghdi() - -advectStress() - -updateTensor() - -stressAdvectionDerivative() - -cauchyJacobian() - -polarDecomposition() - #_small_stress - #_small_jacobian - #_def_grad - #_rotation - #_stretch - } - class ComputeHypoelasticStVenantKirchhoffStress { - +computeQpSmallStress() - #_elasticity_tensor - #_def_grad - } - class ComputeDeformGradBasedStress { - +computeQpStress() - #_deformation_gradient - #_elasticity_tensor - #_stress - #_Jacobian_mult - } - class CZMComputeGlobalTractionTotalLagrangian { - +computeEquilibriumTracionAndDerivatives() - #_F - #_J - #_F_inv - #_area_ratio - #_PK1traction - #_dPK1traction_dF - } - - Material <|-- ComputeLagrangianStressBase - ComputeLagrangianStressBase <|-- ComputeLagrangianStressCauchy - ComputeLagrangianStressBase <|-- ComputeLagrangianStressPK1 - ComputeLagrangianStressPK1 <|-- ComputeLagrangianStressPK2 - ComputeLagrangianStressCauchy <|-- ComputeLagrangianObjectiveStress - ComputeLagrangianObjectiveStress <|-- ComputeHypoelasticStVenantKirchhoffStress - Material <|-- ComputeDeformGradBasedStress - CZMComputeGlobalTractionBase <|-- CZMComputeGlobalTractionTotalLagrangian -` ` ` - -## Code Snippets - -### 1. Pull-back of Cauchy stress to 2nd PK -The direct pull-back of Cauchy stress to 2nd PK is not explicitly shown as a single method. Instead, the framework often computes stresses in one form and then transforms them. For example, `ComputeLagrangianStressPK2` provides the 2nd PK stress and then derives the 1st PK stress from it. - -### 2. Push-forward of 2nd PK to Cauchy -The push-forward of 2nd PK stress to Cauchy stress is performed in `ComputeDeformGradBasedStress::computeQpStress()`: -` ` `cpp - _stress[_qp] = _deformation_gradient[_qp] * pk2 * _deformation_gradient[_qp].transpose() / - _deformation_gradient[_qp].det(); -` ` ` -And in `ComputeLagrangianStressPK1::computeQpCauchyStress()`: -` ` `cpp - _cauchy_stress[_qp] = _pk1_stress[_qp] * _F[_qp].transpose() / _F[_qp].det(); -` ` ` - -### 3. `RankTwoTensor` class methods -The `RankTwoTensor` class itself does not expose methods like `rotate()`, `pushForward()`, or `pullBack()` for general tensor transformations. These operations are typically handled at a higher level within material models, where the context of deformation gradient and Jacobian is available. - -### 4. Elasticity tensor transformation -The push-forward of the 4th-order elasticity tensor is shown in `ComputeHypoelasticStVenantKirchhoffStress::computeQpSmallStress()`: -` ` `cpp - const RankTwoTensor F = _def_grad[_qp]; - const Real J = F.det(); - const RankFourTensor FF = F.times(F); - const RankFourTensor FtFt = F.times(F); - const RankFourTensor C0 = _elasticity_tensor[_qp]; - const RankFourTensor C = FF * C0 * FtFt / J; -` ` ` - -### 5. Tangent modulus transformation for consistent linearization in total Lagrangian -MOOSE handles the tangent modulus transformation for consistent linearization in total Lagrangian formulations through the `_pk1_jacobian` property in `ComputeLagrangianStressBase` and its derivatives in subclasses. For example, `ComputeLagrangianStressPK2::computeQpPK1Stress()` calculates `_pk1_jacobian` based on `_C[_qp]` (2nd PK tangent) and the deformation gradient. The `TotalLagrangianStressDivergenceBase` kernel then uses this `_pk1_jacobian` for its computations. - -### 7. Material vs spatial descriptions -MOOSE converts back and forth between material (reference) and spatial (current) descriptions. The `ComputeLagrangianStressBase` class and its derivatives are designed to handle both Cauchy stress (spatial) and 1st Piola-Kirchhoff stress (material), along with their respective Jacobians. This allows for flexibility in material model implementation while providing the necessary quantities for both total and updated Lagrangian kernels. For instance, `ComputeLagrangianStressCauchy` computes Cauchy stress and then wraps it to get 1st PK stress, - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-algorithm.md b/packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-algorithm.md deleted file mode 100644 index 5b24fa5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-algorithm.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -id: moose-return-mapping-algorithm -title: MOOSE Return mapping algorithm deep dive -domain: constitutive -subdomain: algorithmic -tags: -- return-mapping -- newton-iteration -- bisection -- line-search -- convergence -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-return-mapping-base - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-return-mapping-base -- to: cm-anisotropic-yield - type: implements - weight: 0.8 - note: Newton-Raphson return mapping with fallback strategies ---- - -# MOOSE Return mapping algorithm deep dive - -The `SingleVariableReturnMappingSolution` class in MOOSE provides a framework for solving a scalar nonlinear equation using Newton-Raphson iteration, with optional line search and bisection fallback, to determine an inelastic strain increment. This class is fundamental to various stress update models in solid mechanics, such as `RadialReturnStressUpdate` and `GeneralizedRadialReturnStressUpdate`. - -## Classes & Methods - -* `SingleVariableReturnMappingSolutionTempl::returnMappingSolve(const GenericReal & effective_trial_stress, GenericReal & scalar, const ConsoleStream & console)`: The main entry point for performing the return mapping iterations to solve for the scalar inelastic strain increment. -* `SingleVariableReturnMappingSolutionTempl::computeResidual(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the residual $R(\Delta\gamma)$ of the nonlinear equation. -* `SingleVariableReturnMappingSolutionTempl::computeDerivative(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the derivative of the residual $dR/d\Delta\gamma$. -* `SingleVariableReturnMappingSolutionTempl::computeResidualAndDerivative(const GenericReal & effective_trial_stress, const GenericChainedReal & scalar)`: Computes both the residual and its derivative, used when automatic differentiation is enabled. -* `SingleVariableReturnMappingSolutionTempl::initialGuess(const GenericReal & effective_trial_stress)`: Provides an initial guess for the scalar variable. -* `SingleVariableReturnMappingSolutionTempl::minimumPermissibleValue(const GenericReal & effective_trial_stress)`: Returns the minimum allowed value for the scalar. -* `SingleVariableReturnMappingSolutionTempl::maximumPermissibleValue(const GenericReal & effective_trial_stress)`: Returns the maximum allowed value for the scalar. -* `SingleVariableReturnMappingSolutionTempl::computeReferenceResidual(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes a reference quantity for relative convergence checks. -* `SingleVariableReturnMappingSolutionTempl::internalSolve(const GenericReal effective_trial_stress, GenericReal & scalar, std::stringstream * iter_output)`: The internal method that executes the Newton-Raphson iterations. -* `SingleVariableReturnMappingSolutionTempl::convergedAcceptable(const unsigned int it, const Real reference)`: Checks for acceptable (relaxed) convergence. -* `SingleVariableReturnMappingSolutionTempl::checkPermissibleRange(GenericReal & scalar, GenericReal & scalar_increment, const GenericReal & scalar_old, const GenericReal min_permissible_scalar, const GenericReal max_permissible_scalar, std::stringstream * iter_output)`: Ensures the scalar solution remains within permissible bounds. -* `SingleVariableReturnMappingSolutionTempl::updateBounds(const GenericReal & scalar, const GenericReal & residual, const Real init_resid_sign, GenericReal & scalar_upper_bound, GenericReal & scalar_lower_bound, std::stringstream * iter_output)`: Updates the bounds for bisection fallback. -* `RadialReturnStressUpdateTempl::computeStressInitialize(const GenericReal & effective_trial_stress, const GenericRankFourTensor & elasticity_tensor)`: A hook for derived classes to perform initialization before the return mapping solve. -* `RadialReturnStressUpdateTempl::computeStressFinalize(const GenericRankTwoTensor & inelasticStrainIncrement)`: A hook for derived classes to finalize state after the return mapping solve. - -## Algorithm Steps - -The `SingleVariableReturnMappingSolution` class implements a Newton-Raphson solver with optional line search and bisection fallback. The core algorithm is executed within the `internalSolve` method. - -### 1. Trial Elastic Stress Computation and Effective Stress Evaluation - -Before the return mapping iterations begin, the material model computes a trial elastic stress state. For example, in `RadialReturnStressUpdate`, the deviatoric trial stress is computed from `stress_new`, and then the effective trial stress is calculated as: -$$ \sigma_{eff}^{trial} = \sqrt{\frac{3}{2} \mathbf{s}^{trial} : \mathbf{s}^{trial}} $$ -where $\mathbf{s}^{trial}$ is the deviatoric trial stress. This `effective_trial_stress` is then passed to the `returnMappingSolve` method. - -### 2. Scalar Nonlinear Equation: Residual $R(\Delta\gamma)$ and its Derivative $dR/d\Delta\gamma$ - -The algorithm solves for a scalar variable, typically denoted as $\Delta\gamma$, which represents the effective inelastic strain increment. The specific form of the residual $R(\Delta\gamma)$ and its derivative $dR/d\Delta\gamma$ are model-dependent and must be implemented by derived classes through the `computeResidual` and `computeDerivative` virtual methods, respectively. If automatic differentiation is enabled (`_ad_derivative = true`), the `computeResidualAndDerivative` method must be overridden. The residual is expected to be in strain increment units for consistency. - -### 3. Newton-Raphson Iteration with Line Search - -The `returnMappingSolve` method orchestrates the Newton-Raphson iterations. - -` ` `pseudocode -function returnMappingSolve(effective_trial_stress, scalar) - scalar_old = initialGuess(effective_trial_stress) - residual_old = computeResidual(effective_trial_stress, scalar_old) - derivative_old = computeDerivative(effective_trial_stress, scalar_old) - - loop for _max_its iterations: - scalar_increment = -residual_old / derivative_old - - if _line_search is true: - // Line search activation and procedure - alpha = 1.0 - while (new_residual > (1 - alpha * line_search_tolerance) * residual_old) and (alpha > min_line_search_step_size): - alpha = alpha * 0.5 - scalar_trial = scalar_old + alpha * scalar_increment - new_residual = computeResidual(effective_trial_stress, scalar_trial) - scalar_new = scalar_old + alpha * scalar_increment - else: - scalar_new = scalar_old + scalar_increment - - // Check and enforce permissible range - checkPermissibleRange(scalar_new, scalar_increment, scalar_old, min_permissible_scalar, max_permissible_scalar) - - residual_new = computeResidual(effective_trial_stress, scalar_new) - derivative_new = computeDerivative(effective_trial_stress, scalar_new) - - // Check convergence criteria - if converged(residual_new, reference_residual): - break - - // Update bounds for bisection fallback - updateBounds(scalar_new, residual_new, initial_residual_sign, scalar_upper_bound, scalar_lower_bound) - - scalar_old = scalar_new - residual_old = residual_new - derivative_old = derivative_new -` ` ` - -Line search activates when the `_line_search` parameter is set to `true`. It is used to improve convergence by ensuring that each step reduces the residual. If a full Newton step does not reduce the residual sufficiently, the step size is halved until a reduction is achieved or a minimum step size is reached. - -### 4. Bisection/Bracket Fallback - -If the Newton-Raphson iteration fails to converge or produces a solution outside the permissible range, a bisection method can be used as a fallback if `_bracket_solution` is `true`. The `updateBounds` method maintains upper and lower bounds for the scalar, which are used to bracket the root. If the solution goes out of bounds, it can be reset to the midpoint of the bracket. - -### 5. Convergence Criteria - -Convergence is determined by checking both absolute and relative tolerances against the residual. - -* `_absolute_tolerance`: The absolute tolerance for the residual. -* `_relative_tolerance`: The relative tolerance for the residual, typically compared against a reference residual computed by `computeReferenceResidual`. - -Additionally, an "acceptable convergence" criterion is available, controlled by `_acceptable_multiplier`. The `convergedAcceptable` method checks if the residual is within these relaxed limits, particularly when progress on reducing the residual has stalled. - -### 6. The `_effective_inelastic_strain_increment` Output and Feedback - -The primary output of the `returnMappingSolve` method is the `scalar` variable, which represents the effective inelastic strain increment ($\Delta\gamma$). In derived classes like `RadialReturnStressUpdate`, this scalar is stored in the `_effective_inelastic_strain_increment` member variable. This value is then used to compute the tensorial `inelastic_strain_increment` and update the `stress_new`. The `inelastic_strain_increment` is subtracted from the total `strain_increment` to obtain the elastic strain increment, which is then used to update the stress. - -### 7. `returnMappingSolve()` Entry Point and `computeStressInitialize()`/`computeStressFinalize()` Hooks - -The `returnMappingSolve` method is the entry point for the return mapping algorithm. It is typically called from the `updateState` method of a derived stress update material. For example, in `RadialReturnStressUpdate`, it is called after computing the `effective_trial_stress`. - -The `computeStressInitialize()` and `computeStressFinalize()` methods are virtual hooks provided for derived classes to perform model-specific setup and cleanup tasks before and after the return mapping iterations, respectively. For instance, `RadialReturnStressUpdate` uses `computeStressInitialize` to set up material properties like `_three_shear_modulus` and `computeStressFinalize` to perform any final state updates. - -## Parameters - -* `_relative_tolerance`: `Real` - Relative convergence tolerance. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-base.md b/packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-base.md deleted file mode 100644 index 66d5adb..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-base.md +++ /dev/null @@ -1,311 +0,0 @@ ---- -id: moose-return-mapping-base -title: MOOSE Return Mapping and Radial Return — Extended -domain: constitutive -subdomain: algorithmic -tags: -- return-mapping -- radial-return -- plasticity -- newton-iteration -- convergence -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-stress-computation-chain - type: requires - weight: 0.7 - note: Part of the stress computation dispatch chain -- to: cm-anisotropic-yield - type: implements - weight: 0.8 - note: Implements radial return for yield surface integration -- to: cm-viscoplastic-thermo - type: implements - weight: 0.6 - note: Return mapping used for viscoplastic flow rules ---- - -# MOOSE Return Mapping and Radial Return — Extended - -Framework knowledge node covering 2 aspect(s) of Return Mapping and Radial Return — Extended. - -## Return mapping algorithm deep dive - -The `SingleVariableReturnMappingSolution` class in MOOSE provides a framework for solving a scalar nonlinear equation using Newton-Raphson iteration, with optional line search and bisection fallback, to determine an inelastic strain increment. This class is fundamental to various stress update models in solid mechanics, such as `RadialReturnStressUpdate` and `GeneralizedRadialReturnStressUpdate`. - -## Classes & Methods - -* `SingleVariableReturnMappingSolutionTempl::returnMappingSolve(const GenericReal & effective_trial_stress, GenericReal & scalar, const ConsoleStream & console)`: The main entry point for performing the return mapping iterations to solve for the scalar inelastic strain increment. -* `SingleVariableReturnMappingSolutionTempl::computeResidual(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the residual $R(\Delta\gamma)$ of the nonlinear equation. -* `SingleVariableReturnMappingSolutionTempl::computeDerivative(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the derivative of the residual $dR/d\Delta\gamma$. -* `SingleVariableReturnMappingSolutionTempl::computeResidualAndDerivative(const GenericReal & effective_trial_stress, const GenericChainedReal & scalar)`: Computes both the residual and its derivative, used when automatic differentiation is enabled. -* `SingleVariableReturnMappingSolutionTempl::initialGuess(const GenericReal & effective_trial_stress)`: Provides an initial guess for the scalar variable. -* `SingleVariableReturnMappingSolutionTempl::minimumPermissibleValue(const GenericReal & effective_trial_stress)`: Returns the minimum allowed value for the scalar. -* `SingleVariableReturnMappingSolutionTempl::maximumPermissibleValue(const GenericReal & effective_trial_stress)`: Returns the maximum allowed value for the scalar. -* `SingleVariableReturnMappingSolutionTempl::computeReferenceResidual(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes a reference quantity for relative convergence checks. -* `SingleVariableReturnMappingSolutionTempl::internalSolve(const GenericReal effective_trial_stress, GenericReal & scalar, std::stringstream * iter_output)`: The internal method that executes the Newton-Raphson iterations. -* `SingleVariableReturnMappingSolutionTempl::convergedAcceptable(const unsigned int it, const Real reference)`: Checks for acceptable (relaxed) convergence. -* `SingleVariableReturnMappingSolutionTempl::checkPermissibleRange(GenericReal & scalar, GenericReal & scalar_increment, const GenericReal & scalar_old, const GenericReal min_permissible_scalar, const GenericReal max_permissible_scalar, std::stringstream * iter_output)`: Ensures the scalar solution remains within permissible bounds. -* `SingleVariableReturnMappingSolutionTempl::updateBounds(const GenericReal & scalar, const GenericReal & residual, const Real init_resid_sign, GenericReal & scalar_upper_bound, GenericReal & scalar_lower_bound, std::stringstream * iter_output)`: Updates the bounds for bisection fallback. -* `RadialReturnStressUpdateTempl::computeStressInitialize(const GenericReal & effective_trial_stress, const GenericRankFourTensor & elasticity_tensor)`: A hook for derived classes to perform initialization before the return mapping solve. -* `RadialReturnStressUpdateTempl::computeStressFinalize(const GenericRankTwoTensor & inelasticStrainIncrement)`: A hook for derived classes to finalize state after the return mapping solve. - -## Algorithm Steps - -The `SingleVariableReturnMappingSolution` class implements a Newton-Raphson solver with optional line search and bisection fallback. The core algorithm is executed within the `internalSolve` method. - -### 1. Trial Elastic Stress Computation and Effective Stress Evaluation - -Before the return mapping iterations begin, the material model computes a trial elastic stress state. For example, in `RadialReturnStressUpdate`, the deviatoric trial stress is computed from `stress_new`, and then the effective trial stress is calculated as: -$$ \sigma_{eff}^{trial} = \sqrt{\frac{3}{2} \mathbf{s}^{trial} : \mathbf{s}^{trial}} $$ -where $\mathbf{s}^{trial}$ is the deviatoric trial stress. This `effective_trial_stress` is then passed to the `returnMappingSolve` method. - -### 2. Scalar Nonlinear Equation: Residual $R(\Delta\gamma)$ and its Derivative $dR/d\Delta\gamma$ - -The algorithm solves for a scalar variable, typically denoted as $\Delta\gamma$, which represents the effective inelastic strain increment. The specific form of the residual $R(\Delta\gamma)$ and its derivative $dR/d\Delta\gamma$ are model-dependent and must be implemented by derived classes through the `computeResidual` and `computeDerivative` virtual methods, respectively. If automatic differentiation is enabled (`_ad_derivative = true`), the `computeResidualAndDerivative` method must be overridden. The residual is expected to be in strain increment units for consistency. - -### 3. Newton-Raphson Iteration with Line Search - -The `returnMappingSolve` method orchestrates the Newton-Raphson iterations. - -` ` `pseudocode -function returnMappingSolve(effective_trial_stress, scalar) - scalar_old = initialGuess(effective_trial_stress) - residual_old = computeResidual(effective_trial_stress, scalar_old) - derivative_old = computeDerivative(effective_trial_stress, scalar_old) - - loop for _max_its iterations: - scalar_increment = -residual_old / derivative_old - - if _line_search is true: - // Line search activation and procedure - alpha = 1.0 - while (new_residual > (1 - alpha * line_search_tolerance) * residual_old) and (alpha > min_line_search_step_size): - alpha = alpha * 0.5 - scalar_trial = scalar_old + alpha * scalar_increment - new_residual = computeResidual(effective_trial_stress, scalar_trial) - scalar_new = scalar_old + alpha * scalar_increment - else: - scalar_new = scalar_old + scalar_increment - - // Check and enforce permissible range - checkPermissibleRange(scalar_new, scalar_increment, scalar_old, min_permissible_scalar, max_permissible_scalar) - - residual_new = computeResidual(effective_trial_stress, scalar_new) - derivative_new = computeDerivative(effective_trial_stress, scalar_new) - - // Check convergence criteria - if converged(residual_new, reference_residual): - break - - // Update bounds for bisection fallback - updateBounds(scalar_new, residual_new, initial_residual_sign, scalar_upper_bound, scalar_lower_bound) - - scalar_old = scalar_new - residual_old = residual_new - derivative_old = derivative_new -` ` ` - -Line search activates when the `_line_search` parameter is set to `true`. It is used to improve convergence by ensuring that each step reduces the residual. If a full Newton step does not reduce the residual sufficiently, the step size is halved until a reduction is achieved or a minimum step size is reached. - -### 4. Bisection/Bracket Fallback - -If the Newton-Raphson iteration fails to converge or produces a solution outside the permissible range, a bisection method can be used as a fallback if `_bracket_solution` is `true`. The `updateBounds` method maintains upper and lower bounds for the scalar, which are used to bracket the root. If the solution goes out of bounds, it can be reset to the midpoint of the bracket. - -### 5. Convergence Criteria - -Convergence is determined by checking both absolute and relative tolerances against the residual. - -* `_absolute_tolerance`: The absolute tolerance for the residual. -* `_relative_tolerance`: The relative tolerance for the residual, typically compared against a reference residual computed by `computeReferenceResidual`. - -Additionally, an "acceptable convergence" criterion is available, controlled by `_acceptable_multiplier`. The `convergedAcceptable` method checks if the residual is within these relaxed limits, particularly when progress on reducing the residual has stalled. - -### 6. The `_effective_inelastic_strain_increment` Output and Feedback - -The primary output of the `returnMappingSolve` method is the `scalar` variable, which represents the effective inelastic strain increment ($\Delta\gamma$). In derived classes like `RadialReturnStressUpdate`, this scalar is stored in the `_effective_inelastic_strain_increment` member variable. This value is then used to compute the tensorial `inelastic_strain_increment` and update the `stress_new`. The `inelastic_strain_increment` is subtracted from the total `strain_increment` to obtain the elastic strain increment, which is then used to update the stress. - -### 7. `returnMappingSolve()` Entry Point and `computeStressInitialize()`/`computeStressFinalize()` Hooks - -The `returnMappingSolve` method is the entry point for the return mapping algorithm. It is typically called from the `updateState` method of a derived stress update material. For example, in `RadialReturnStressUpdate`, it is called after computing the `effective_trial_stress`. - -The `computeStressInitialize()` and `computeStressFinalize()` methods are virtual hooks provided for derived classes to perform model-specific setup and cleanup tasks before and after the return mapping iterations, respectively. For instance, `RadialReturnStressUpdate` uses `computeStressInitialize` to set up material properties like `_three_shear_modulus` and `computeStressFinalize` to perform any final state updates. - -## Parameters - -* `_relative_tolerance`: `Real` - Relative convergence tolerance. - - -## Extending radial return for new constitutive models - -To implement a new inelastic material model using the radial return framework in MOOSE, you will primarily interact with the `RadialReturnStressUpdate` base class or one of its specialized derivatives. The process involves defining the material's constitutive behavior, managing history variables, and registering the model for use by `ComputeMultipleInelasticStress`. - -## Classes & Methods - -### Base Class Selection - -You should inherit from `RadialReturnStressUpdateTempl` for isotropic inelastic models. If your model is for creep, consider `RadialReturnCreepStressUpdateBaseTempl` , and for isotropic plasticity, `IsotropicPlasticityStressUpdateTempl` . For anisotropic models, `GeneralizedRadialReturnStressUpdateTempl` is the appropriate base class, with further specializations like `AnisotropicReturnCreepStressUpdateBaseTempl` or `AnisotropicReturnPlasticityStressUpdateBaseTempl` for specific anisotropic behaviors. - -### Virtual Methods to Override - -The following virtual methods from `RadialReturnStressUpdateTempl` must be overridden to define your material's behavior: - -* `computeStressInitialize(const GenericReal & effective_trial_stress, const GenericRankFourTensor & elasticity_tensor)`: Initializes stress-related quantities at the beginning of a stress update step. -* `computeResidual(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the residual of the yield function or flow rule. This is the function whose root is sought by the Newton solver. -* `computeDerivative(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the derivative of the residual with respect to the scalar inelastic strain increment. -* `computeStressFinalize(const GenericRankTwoTensor & plastic_strain_increment)`: Finalizes the stress state and updates history variables after the return mapping iterations converge. - -For models inheriting from `RadialReturnCreepStressUpdateBaseTempl`, you might also need to override `computeStressDerivative` for non-AD versions . - -### Class Skeleton Example - -Here's a skeleton for a new isotropic inelastic material model, demonstrating the required overrides: - -` ` `cpp -template -class MyNewInelasticModelTempl : public RadialReturnStressUpdateTempl -{ -public: - static InputParameters validParams() - { - InputParameters params = RadialReturnStressUpdateTempl::validParams(); - // Add specific parameters for your model here - return params; - } - - MyNewInelasticModelTempl(const InputParameters & parameters) - : RadialReturnStressUpdateTempl(parameters), - _my_history_variable(this->template declareGenericProperty(this->_base_name + "my_history_variable")), - _my_history_variable_old(this->template getMaterialPropertyOld(this->_base_name + "my_history_variable")) - { - // Initialize any member variables - } - -protected: - // Override virtual methods - virtual void computeStressInitialize(const GenericReal & effective_trial_stress, - const GenericRankFourTensor & elasticity_tensor) override - { - // Implement initialization logic - RadialReturnStressUpdateTempl::computeStressInitialize(effective_trial_stress, elasticity_tensor); - } - - virtual GenericReal computeResidual(const GenericReal & effective_trial_stress, - const GenericReal & scalar) override - { - // Implement your yield function or flow rule residual - // Example: return effective_trial_stress - 3 * G * scalar - yield_stress; - return 0.0; // Placeholder - } - - virtual GenericReal computeDerivative(const GenericReal & effective_trial_stress, - const GenericReal & scalar) override - { - // Implement the derivative of the residual with respect to 'scalar' - // Example: return -3 * G; - return 0.0; // Placeholder - } - - virtual void computeStressFinalize(const GenericRankTwoTensor & inelastic_strain_increment) override - { - // Update history variables and perform any final calculations - _my_history_variable[this->_qp] = _my_history_variable_old[this->_qp] + inelastic_strain_increment.trace(); // Example update - RadialReturnStressUpdateTempl::computeStressFinalize(inelastic_strain_increment); - } - - virtual void initQpStatefulProperties() override - { - _my_history_variable[this->_qp] = 0.0; // Initialize to zero at the start of a new simulation - RadialReturnStressUpdateTempl::initQpStatefulProperties(); - } - - virtual void propagateQpStatefulProperties() override - { - _my_history_variable[this->_qp] = _my_history_variable_old[this->_qp]; // Propagate old value - RadialReturnStressUpdateTempl::propagateQpStatefulProperties(); - } - - // Declare stateful material properties - GenericMaterialProperty & _my_history_variable; - const MaterialProperty & _my_history_variable_old; -}; - -typedef MyNewInelasticModelTempl MyNewInelasticModel; -typedef MyNewInelasticModelTempl ADMyNewInelasticModel; -` ` ` - -### History Variables (Stateful MaterialProperties) - -History variables are managed as stateful `MaterialProperty` objects. You declare them in your class header and initialize them in the constructor and `initQpStatefulProperties()` method. - -For example, to declare a history variable `_my_history_variable` of type `Real`: - -` ` `cpp - GenericMaterialProperty & _my_history_variable; - const MaterialProperty & _my_history_variable_old; -` ` ` - -In the constructor, you associate these with material properties: - -` ` `cpp - MyNewInelasticModelTempl(const InputParameters & parameters) - : RadialReturnStressUpdateTempl(parameters), - _my_history_variable(this->template declareGenericProperty(this->_base_name + "my_history_variable")), - _my_history_variable_old(this->template getMaterialPropertyOld(this->_base_name + "my_history_variable")) - { - } -` ` ` - -You must override `initQpStatefulProperties()` to set initial values (e.g., zero) and `propagateQpStatefulProperties()` to carry over values from the previous time step. - -### Registration with `ComputeMultipleInelasticStress` - -To make your new material model usable by `ComputeMultipleInelasticStress`, you need to register it using `registerMooseObject`. This is typically done in the `.C` file of your material. - -` ` `cpp -registerMooseObject("SolidMechanicsApp", MyNewInelasticModel); -` ` ` - -Then, in your MOOSE input file, you list your material model under the `inelastic_models` parameter of `ComputeMultipleInelasticStress`. - -` ` `ini -[Materials] - [my_inelastic_model] - type = MyNewInelasticModel - # ... parameters for your model ... - [] - [combined_inelastic_stress] - type = ComputeMultipleInelasticStress - inelastic_models = 'my_inelastic_model' - # ... other parameters ... - [] -[] -` ` ` - -## Example: `IsotropicPlasticityStressUpdate` - -The `IsotropicPlasticityStressUpdate` class provides a concrete example of this pattern. - -**Inheritance:** It inherits from `RadialReturnStressUpdateTempl`. - -**Overridden Methods:** -* `computeStressInitialize`: Initializes the yield stress and hardening slope. -* `computeResidual`: Calculates the residual of the yield function. -* `computeDerivative`: Computes the derivative of the residual. -* `computeStressFinalize`: Updates the plastic strain history variable. -* `initQpStatefulProperties`: Initializes `_plastic_strain` and `_hardening_variable` to zero. -* `propagateQpStatefulProperties`: Propagates `_plastic_strain` and `_hardening_variable` from the old time step. - -**History Variables:** It declares `_plastic_strain`, `_plastic_strain_old`, `_hardening_variable`, and `_hardening_variable_old` as stateful material properties. - -## Notes - -The `is_ad` template parameter indicates whether the class supports Automatic Differentiation. For new models, it's recommended to implement both `false` (for `Real` types) and `true` (for `ADReal` types) versions to leverage MOOSE's AD capabilities for Jacobian computation. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-extension.md b/packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-extension.md deleted file mode 100644 index af390b5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-return-mapping-extension.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: moose-return-mapping-extension -title: MOOSE Extending radial return for new constitutive models -domain: constitutive -subdomain: procedural -tags: -- radial-return -- stress-update-base -- registration -- history-variables -- validParams -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-return-mapping-base - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-return-mapping-base ---- - -# MOOSE Extending radial return for new constitutive models - -To implement a new inelastic material model using the radial return framework in MOOSE, you will primarily interact with the `RadialReturnStressUpdate` base class or one of its specialized derivatives. The process involves defining the material's constitutive behavior, managing history variables, and registering the model for use by `ComputeMultipleInelasticStress`. - -## Classes & Methods - -### Base Class Selection - -You should inherit from `RadialReturnStressUpdateTempl` for isotropic inelastic models. If your model is for creep, consider `RadialReturnCreepStressUpdateBaseTempl` , and for isotropic plasticity, `IsotropicPlasticityStressUpdateTempl` . For anisotropic models, `GeneralizedRadialReturnStressUpdateTempl` is the appropriate base class, with further specializations like `AnisotropicReturnCreepStressUpdateBaseTempl` or `AnisotropicReturnPlasticityStressUpdateBaseTempl` for specific anisotropic behaviors. - -### Virtual Methods to Override - -The following virtual methods from `RadialReturnStressUpdateTempl` must be overridden to define your material's behavior: - -* `computeStressInitialize(const GenericReal & effective_trial_stress, const GenericRankFourTensor & elasticity_tensor)`: Initializes stress-related quantities at the beginning of a stress update step. -* `computeResidual(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the residual of the yield function or flow rule. This is the function whose root is sought by the Newton solver. -* `computeDerivative(const GenericReal & effective_trial_stress, const GenericReal & scalar)`: Computes the derivative of the residual with respect to the scalar inelastic strain increment. -* `computeStressFinalize(const GenericRankTwoTensor & plastic_strain_increment)`: Finalizes the stress state and updates history variables after the return mapping iterations converge. - -For models inheriting from `RadialReturnCreepStressUpdateBaseTempl`, you might also need to override `computeStressDerivative` for non-AD versions . - -### Class Skeleton Example - -Here's a skeleton for a new isotropic inelastic material model, demonstrating the required overrides: - -` ` `cpp -template -class MyNewInelasticModelTempl : public RadialReturnStressUpdateTempl -{ -public: - static InputParameters validParams() - { - InputParameters params = RadialReturnStressUpdateTempl::validParams(); - // Add specific parameters for your model here - return params; - } - - MyNewInelasticModelTempl(const InputParameters & parameters) - : RadialReturnStressUpdateTempl(parameters), - _my_history_variable(this->template declareGenericProperty(this->_base_name + "my_history_variable")), - _my_history_variable_old(this->template getMaterialPropertyOld(this->_base_name + "my_history_variable")) - { - // Initialize any member variables - } - -protected: - // Override virtual methods - virtual void computeStressInitialize(const GenericReal & effective_trial_stress, - const GenericRankFourTensor & elasticity_tensor) override - { - // Implement initialization logic - RadialReturnStressUpdateTempl::computeStressInitialize(effective_trial_stress, elasticity_tensor); - } - - virtual GenericReal computeResidual(const GenericReal & effective_trial_stress, - const GenericReal & scalar) override - { - // Implement your yield function or flow rule residual - // Example: return effective_trial_stress - 3 * G * scalar - yield_stress; - return 0.0; // Placeholder - } - - virtual GenericReal computeDerivative(const GenericReal & effective_trial_stress, - const GenericReal & scalar) override - { - // Implement the derivative of the residual with respect to 'scalar' - // Example: return -3 * G; - return 0.0; // Placeholder - } - - virtual void computeStressFinalize(const GenericRankTwoTensor & inelastic_strain_increment) override - { - // Update history variables and perform any final calculations - _my_history_variable[this->_qp] = _my_history_variable_old[this->_qp] + inelastic_strain_increment.trace(); // Example update - RadialReturnStressUpdateTempl::computeStressFinalize(inelastic_strain_increment); - } - - virtual void initQpStatefulProperties() override - { - _my_history_variable[this->_qp] = 0.0; // Initialize to zero at the start of a new simulation - RadialReturnStressUpdateTempl::initQpStatefulProperties(); - } - - virtual void propagateQpStatefulProperties() override - { - _my_history_variable[this->_qp] = _my_history_variable_old[this->_qp]; // Propagate old value - RadialReturnStressUpdateTempl::propagateQpStatefulProperties(); - } - - // Declare stateful material properties - GenericMaterialProperty & _my_history_variable; - const MaterialProperty & _my_history_variable_old; -}; - -typedef MyNewInelasticModelTempl MyNewInelasticModel; -typedef MyNewInelasticModelTempl ADMyNewInelasticModel; -` ` ` - -### History Variables (Stateful MaterialProperties) - -History variables are managed as stateful `MaterialProperty` objects. You declare them in your class header and initialize them in the constructor and `initQpStatefulProperties()` method. - -For example, to declare a history variable `_my_history_variable` of type `Real`: - -` ` `cpp - GenericMaterialProperty & _my_history_variable; - const MaterialProperty & _my_history_variable_old; -` ` ` - -In the constructor, you associate these with material properties: - -` ` `cpp - MyNewInelasticModelTempl(const InputParameters & parameters) - : RadialReturnStressUpdateTempl(parameters), - _my_history_variable(this->template declareGenericProperty(this->_base_name + "my_history_variable")), - _my_history_variable_old(this->template getMaterialPropertyOld(this->_base_name + "my_history_variable")) - { - } -` ` ` - -You must override `initQpStatefulProperties()` to set initial values (e.g., zero) and `propagateQpStatefulProperties()` to carry over values from the previous time step. - -### Registration with `ComputeMultipleInelasticStress` - -To make your new material model usable by `ComputeMultipleInelasticStress`, you need to register it using `registerMooseObject`. This is typically done in the `.C` file of your material. - -` ` `cpp -registerMooseObject("SolidMechanicsApp", MyNewInelasticModel); -` ` ` - -Then, in your MOOSE input file, you list your material model under the `inelastic_models` parameter of `ComputeMultipleInelasticStress`. - -` ` `ini -[Materials] - [my_inelastic_model] - type = MyNewInelasticModel - # ... parameters for your model ... - [] - [combined_inelastic_stress] - type = ComputeMultipleInelasticStress - inelastic_models = 'my_inelastic_model' - # ... other parameters ... - [] -[] -` ` ` - -## Example: `IsotropicPlasticityStressUpdate` - -The `IsotropicPlasticityStressUpdate` class provides a concrete example of this pattern. - -**Inheritance:** It inherits from `RadialReturnStressUpdateTempl`. - -**Overridden Methods:** -* `computeStressInitialize`: Initializes the yield stress and hardening slope. -* `computeResidual`: Calculates the residual of the yield function. -* `computeDerivative`: Computes the derivative of the residual. -* `computeStressFinalize`: Updates the plastic strain history variable. -* `initQpStatefulProperties`: Initializes `_plastic_strain` and `_hardening_variable` to zero. -* `propagateQpStatefulProperties`: Propagates `_plastic_strain` and `_hardening_variable` from the old time step. - -**History Variables:** It declares `_plastic_strain`, `_plastic_strain_old`, `_hardening_variable`, and `_hardening_variable_old` as stateful material properties. - -## Notes - -The `is_ad` template parameter indicates whether the class supports Automatic Differentiation. For new models, it's recommended to implement both `false` (for `Real` types) and `true` (for `ADReal` types) versions to leverage MOOSE's AD capabilities for Jacobian computation. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-strain-classes.md b/packages/akms/src/akms/_bundled/global_nodes/moose-strain-classes.md deleted file mode 100644 index 9c2d918..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-strain-classes.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: moose-strain-classes -title: MOOSE Strain computation classes and formulations -domain: constitutive -subdomain: algorithmic -tags: -- small-strain -- incremental-strain -- finite-strain -- deformation-gradient -- polar-decomposition -- volumetric-locking -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-strain-formulations - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-strain-formulations -- to: cm-kinematics-tl - type: implements - weight: 0.9 - note: Strain computation hierarchy from small to finite ---- - -# MOOSE Strain computation classes and formulations - -This response describes how MOOSE computes strains in the Tensor Mechanics module, covering small strain, incremental small strain, finite strain, and related concepts like eigenstrain subtraction and volumetric locking. The explanation focuses on the `ComputeSmallStrain` and `ComputeFiniteStrain` classes and their associated methods and parameters. - -## Classes & Methods - -* `ComputeStrainBase` : Base class for strain tensor computations. -* `ComputeStrainBase::validParams()` : Defines common input parameters for strain computation classes, including `displacements`, `base_name`, `volumetric_locking_correction`, `eigenstrain_names`, and `global_strain`. -* `ComputeStrainBase::_mechanical_strain` : Material property representing the mechanical strain. -* `ComputeStrainBase::_total_strain` : Material property representing the total strain. -* `ComputeSmallStrain` : Computes small, total strain for linear elasticity problems. -* `ComputeSmallStrain::computeProperties()` : Calculates the small strain tensor. -* `ComputeIncrementalStrainBase` : Base class for incremental strain formulations. -* `ComputeIncrementalStrainBase::subtractEigenstrainIncrementFromStrain()` : Subtracts eigenstrain increments from the calculated strain. -* `ComputeFiniteStrain` : Computes strain and rotation increments for finite strains. -* `ComputeFiniteStrain::computeProperties()` : Calculates the incremental deformation gradient and handles volumetric locking correction. -* `ComputeFiniteStrain::computeQpStrain()` : Computes the strain increment and updates total and mechanical strains. -* `ComputeFiniteStrain::computeQpIncrements()` : Calculates strain and rotation increments based on the chosen decomposition method. -* `ComputeFiniteStrain::decompositionType()` : Returns the available decomposition methods for finite strain. - -## Relationships - -` ` `mermaid -classDiagram - class Material { - +InputParameters validParams() - } - class ComputeStrainBase { - +InputParameters validParams() - +void initialSetup() - #MaterialProperty& _mechanical_strain - #MaterialProperty& _total_strain - #std::vector*> _eigenstrains - #bool _volumetric_locking_correction - } - class ComputeSmallStrain { - +void computeProperties() - } - class ComputeIncrementalStrainBase { - +void initialSetup() - #void subtractEigenstrainIncrementFromStrain(RankTwoTensor& strain) - #std::vector _grad_disp_old - #MaterialProperty& _strain_increment - #MaterialProperty& _rotation_increment - #MaterialProperty& _deformation_gradient - #const MaterialProperty& _mechanical_strain_old - #const MaterialProperty& _total_strain_old - } - class ComputeFiniteStrain { - +InputParameters validParams() - +void computeProperties() - #void computeQpStrain() - #void computeQpIncrements(RankTwoTensor& e, RankTwoTensor& r) - #std::vector _Fhat - #DecompMethod _decomposition_method - #bool _use_hw - } - - Material <|-- ComputeStrainBase - ComputeStrainBase <|-- ComputeSmallStrain - ComputeStrainBase <|-- ComputeIncrementalStrainBase - ComputeIncrementalStrainBase <|-- ComputeFiniteStrain -` ` ` - -## 1. `ComputeSmallStrain` — linearized strain ε = ½(∇u + ∇uᵀ) - -The `ComputeSmallStrain` class calculates the small, total strain for linear elasticity problems . The linearized small strain is defined as: -$$ -\epsilon = \frac{1}{2} \left( \nabla u + (\nabla u)^T \right) \quad \text{when} \quad \frac{\partial u}{ \partial x} << 1 -$$ -This calculation is performed in the `ComputeSmallStrain::computeProperties()` method . The displacement gradient `grad_tensor` is obtained from the coupled displacement variables `_grad_disp` . The `_total_strain` material property is then updated with this calculated strain . - -` ` `cpp -// strain = (grad_disp + grad_disp^T)/2 -const auto grad_tensor = RankTwoTensor ::initializeFromRows( - (*_grad_disp[0])[_qp], (*_grad_disp[1])[_qp], (*_grad_disp[2])[_qp]); - -_total_strain[_qp] = (grad_tensor + grad_tensor.transpose()) / 2.0; -` ` ` - -## 2. `ComputeIncrementalSmallStrain` — incremental formulation, how is the strain increment Δε computed? - -The prompt mentions `ComputeIncrementalSmallStrain`, but the codebase primarily uses `ComputeIncrementalStrainBase` as the base class for incremental formulations . The strain increment is computed in derived classes like `ComputeFiniteStrain`. The `_strain_increment` material property stores this value . - -## 3. `ComputeFiniteStrain` — the multiplicative decomposition F = R·U, how are the deformation gradient F, rotation R, and stretch U computed? What decomposition method is used (polar, Hughes-Winget)? - -In `ComputeFiniteStrain`, the deformation gradient $F$ is represented by `_deformation_gradient` . The incremental deformation gradient, $\hat{F}$, is computed in `ComputeFiniteStrain::computeProperties()` . -The decomposition of $\hat{F}$ into rotation $\hat{R}$ and stretch $\hat{U}$ (or related quantities) is handled within `ComputeFiniteStrain::computeQpIncrements()` . - -MOOSE supports three decomposition methods for finite strain : -* `TaylorExpansion` (default) -* `EigenSolution` -* `HughesWinget` - -The choice is made via the `decomposition_method` parameter . - -### Taylor Expansion Method -This method approximates the strain increment and rotation increment using a Taylor expansion of the incremental deformation gradient . The strain increment `total_strain_increment` is calculated from `Cinv_I` . The rotation increment `rotation_increment` is computed using components `a`, `C1`, `C2`, and `C3` derived from the inverse of `_Fhat` . - -### Eigen Solution Method -This method uses the polar decomposition approach. It computes the right stretch tensor $\hat{U}$ from $\hat{C} = \hat{F}^T \hat{F}$ using `MathUtils::sqrt(Chat)` . The rotation increment $\hat{R}$ is then calculated as $\hat{F} \hat{U}^{-1}$ . The strain increment is obtained by taking the logarithm of $\hat{U}$ . -$$ -\hat{\boldsymbol{U}} = \sqrt{\lambda_{1}}\boldsymbol{N}_{1} + \sqrt{\lambda_{2}}\boldsymbol{N}_{2} + \sqrt{\lambda_{3}}\boldsymbol{N}_{3} -$$ -$$ -\hat{\boldsymbol{R}} = \hat{\boldsymbol{F}} \hat{\boldsymbol{U}}^{-1} -$$ -The strain increment is given by: -$$ -\boldsymbol{D} = \log{\sqrt{\lambda_{1}}}\boldsymbol{N}_{1} + \log{\sqrt{\lambda_{2}}}\boldsymbol{N}_{2} + \log{\sqrt{\lambda_{3}}}\boldsymbol{N}_{3} -$$ - -### Hughes-Winget Method -This method approximates the stretching rate tensor $\boldsymbol{D}$ and incremental rotation matrix $\hat{\boldsymbol{R}}$ based on the spatial gradient $\boldsymbol{G}$ of the displacement field evaluated at the mid-point of the time step . -The spatial gradient $\boldsymbol{G}$ is computed as: -$$ -\boldsymbol{G} = 2\left( \hat{\boldsymbol{F}} - \boldsymbol{I}\right) \left( \hat{\boldsymbol{F}} + \boldsymbol{I}\right)^{-1} -$$ -The approximate stretching rate tensor (strain increment) is: -$$ -\boldsymbol{D} = \frac{1}{2 \Delta t}\left(\boldsymbol{G} + \boldsymbol{G}^{T} \right) -$$ -The incremental rotation matrix is approximated by: -$$ -\hat{\boldsymbol{R}} = \left(\boldsymbol{I} + \frac{1}{2}\omega \right) \left(\boldsymbol{I} - \frac{1}{2}\omega \right)^{-1} -$$ -where $\omega = \frac{1}{2}\left(\boldsymbol{G} - \boldsymbol{G}^{T} \right)$ . -In the code, `total_strain_increment` is `0.5 * (G + G.transpose())` and `rotation_increment` is `Q_1.inverse() * Q_2` . - -## 4. Strain increment in finite strain: how is the incremental deformation gradient F_incr = F_new · F_old⁻¹ computed? - -The incremental deformation gradient, denoted as `_Fhat` in the code, is computed in `ComputeFiniteStrain::computeProperties()` . -The calculation involves: -1. `A = gradU` (current displacement gradient) . -2. `Fbar = gradUold` (old displacement gradient) . -3. `A = gradU - gradUold` . -4. `Fbar = - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-strain-formulations.md b/packages/akms/src/akms/_bundled/global_nodes/moose-strain-formulations.md deleted file mode 100644 index d49f402..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-strain-formulations.md +++ /dev/null @@ -1,318 +0,0 @@ ---- -id: moose-strain-formulations -title: MOOSE Kinematics — Strain Formulations -domain: constitutive -subdomain: algorithmic -tags: -- kinematics -- small-strain -- finite-strain -- deformation-gradient -- eigenstrain -- thermal-expansion -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: moose-stress-computation-chain - type: requires - weight: 0.7 - note: Part of the stress computation dispatch chain -- to: cm-kinematics-tl - type: implements - weight: 0.9 - note: Implements finite strain kinematics and deformation gradient computation ---- - -# MOOSE Kinematics — Strain Formulations - -Framework knowledge node covering 2 aspect(s) of Kinematics — Strain Formulations. - -## Strain computation classes and formulations - -This response describes how MOOSE computes strains in the Tensor Mechanics module, covering small strain, incremental small strain, finite strain, and related concepts like eigenstrain subtraction and volumetric locking. The explanation focuses on the `ComputeSmallStrain` and `ComputeFiniteStrain` classes and their associated methods and parameters. - -## Classes & Methods - -* `ComputeStrainBase` : Base class for strain tensor computations. -* `ComputeStrainBase::validParams()` : Defines common input parameters for strain computation classes, including `displacements`, `base_name`, `volumetric_locking_correction`, `eigenstrain_names`, and `global_strain`. -* `ComputeStrainBase::_mechanical_strain` : Material property representing the mechanical strain. -* `ComputeStrainBase::_total_strain` : Material property representing the total strain. -* `ComputeSmallStrain` : Computes small, total strain for linear elasticity problems. -* `ComputeSmallStrain::computeProperties()` : Calculates the small strain tensor. -* `ComputeIncrementalStrainBase` : Base class for incremental strain formulations. -* `ComputeIncrementalStrainBase::subtractEigenstrainIncrementFromStrain()` : Subtracts eigenstrain increments from the calculated strain. -* `ComputeFiniteStrain` : Computes strain and rotation increments for finite strains. -* `ComputeFiniteStrain::computeProperties()` : Calculates the incremental deformation gradient and handles volumetric locking correction. -* `ComputeFiniteStrain::computeQpStrain()` : Computes the strain increment and updates total and mechanical strains. -* `ComputeFiniteStrain::computeQpIncrements()` : Calculates strain and rotation increments based on the chosen decomposition method. -* `ComputeFiniteStrain::decompositionType()` : Returns the available decomposition methods for finite strain. - -## Relationships - -` ` `mermaid -classDiagram - class Material { - +InputParameters validParams() - } - class ComputeStrainBase { - +InputParameters validParams() - +void initialSetup() - #MaterialProperty& _mechanical_strain - #MaterialProperty& _total_strain - #std::vector*> _eigenstrains - #bool _volumetric_locking_correction - } - class ComputeSmallStrain { - +void computeProperties() - } - class ComputeIncrementalStrainBase { - +void initialSetup() - #void subtractEigenstrainIncrementFromStrain(RankTwoTensor& strain) - #std::vector _grad_disp_old - #MaterialProperty& _strain_increment - #MaterialProperty& _rotation_increment - #MaterialProperty& _deformation_gradient - #const MaterialProperty& _mechanical_strain_old - #const MaterialProperty& _total_strain_old - } - class ComputeFiniteStrain { - +InputParameters validParams() - +void computeProperties() - #void computeQpStrain() - #void computeQpIncrements(RankTwoTensor& e, RankTwoTensor& r) - #std::vector _Fhat - #DecompMethod _decomposition_method - #bool _use_hw - } - - Material <|-- ComputeStrainBase - ComputeStrainBase <|-- ComputeSmallStrain - ComputeStrainBase <|-- ComputeIncrementalStrainBase - ComputeIncrementalStrainBase <|-- ComputeFiniteStrain -` ` ` - -## 1. `ComputeSmallStrain` — linearized strain ε = ½(∇u + ∇uᵀ) - -The `ComputeSmallStrain` class calculates the small, total strain for linear elasticity problems . The linearized small strain is defined as: -$$ -\epsilon = \frac{1}{2} \left( \nabla u + (\nabla u)^T \right) \quad \text{when} \quad \frac{\partial u}{ \partial x} << 1 -$$ -This calculation is performed in the `ComputeSmallStrain::computeProperties()` method . The displacement gradient `grad_tensor` is obtained from the coupled displacement variables `_grad_disp` . The `_total_strain` material property is then updated with this calculated strain . - -` ` `cpp -// strain = (grad_disp + grad_disp^T)/2 -const auto grad_tensor = RankTwoTensor ::initializeFromRows( - (*_grad_disp[0])[_qp], (*_grad_disp[1])[_qp], (*_grad_disp[2])[_qp]); - -_total_strain[_qp] = (grad_tensor + grad_tensor.transpose()) / 2.0; -` ` ` - -## 2. `ComputeIncrementalSmallStrain` — incremental formulation, how is the strain increment Δε computed? - -The prompt mentions `ComputeIncrementalSmallStrain`, but the codebase primarily uses `ComputeIncrementalStrainBase` as the base class for incremental formulations . The strain increment is computed in derived classes like `ComputeFiniteStrain`. The `_strain_increment` material property stores this value . - -## 3. `ComputeFiniteStrain` — the multiplicative decomposition F = R·U, how are the deformation gradient F, rotation R, and stretch U computed? What decomposition method is used (polar, Hughes-Winget)? - -In `ComputeFiniteStrain`, the deformation gradient $F$ is represented by `_deformation_gradient` . The incremental deformation gradient, $\hat{F}$, is computed in `ComputeFiniteStrain::computeProperties()` . -The decomposition of $\hat{F}$ into rotation $\hat{R}$ and stretch $\hat{U}$ (or related quantities) is handled within `ComputeFiniteStrain::computeQpIncrements()` . - -MOOSE supports three decomposition methods for finite strain : -* `TaylorExpansion` (default) -* `EigenSolution` -* `HughesWinget` - -The choice is made via the `decomposition_method` parameter . - -### Taylor Expansion Method -This method approximates the strain increment and rotation increment using a Taylor expansion of the incremental deformation gradient . The strain increment `total_strain_increment` is calculated from `Cinv_I` . The rotation increment `rotation_increment` is computed using components `a`, `C1`, `C2`, and `C3` derived from the inverse of `_Fhat` . - -### Eigen Solution Method -This method uses the polar decomposition approach. It computes the right stretch tensor $\hat{U}$ from $\hat{C} = \hat{F}^T \hat{F}$ using `MathUtils::sqrt(Chat)` . The rotation increment $\hat{R}$ is then calculated as $\hat{F} \hat{U}^{-1}$ . The strain increment is obtained by taking the logarithm of $\hat{U}$ . -$$ -\hat{\boldsymbol{U}} = \sqrt{\lambda_{1}}\boldsymbol{N}_{1} + \sqrt{\lambda_{2}}\boldsymbol{N}_{2} + \sqrt{\lambda_{3}}\boldsymbol{N}_{3} -$$ -$$ -\hat{\boldsymbol{R}} = \hat{\boldsymbol{F}} \hat{\boldsymbol{U}}^{-1} -$$ -The strain increment is given by: -$$ -\boldsymbol{D} = \log{\sqrt{\lambda_{1}}}\boldsymbol{N}_{1} + \log{\sqrt{\lambda_{2}}}\boldsymbol{N}_{2} + \log{\sqrt{\lambda_{3}}}\boldsymbol{N}_{3} -$$ - -### Hughes-Winget Method -This method approximates the stretching rate tensor $\boldsymbol{D}$ and incremental rotation matrix $\hat{\boldsymbol{R}}$ based on the spatial gradient $\boldsymbol{G}$ of the displacement field evaluated at the mid-point of the time step . -The spatial gradient $\boldsymbol{G}$ is computed as: -$$ -\boldsymbol{G} = 2\left( \hat{\boldsymbol{F}} - \boldsymbol{I}\right) \left( \hat{\boldsymbol{F}} + \boldsymbol{I}\right)^{-1} -$$ -The approximate stretching rate tensor (strain increment) is: -$$ -\boldsymbol{D} = \frac{1}{2 \Delta t}\left(\boldsymbol{G} + \boldsymbol{G}^{T} \right) -$$ -The incremental rotation matrix is approximated by: -$$ -\hat{\boldsymbol{R}} = \left(\boldsymbol{I} + \frac{1}{2}\omega \right) \left(\boldsymbol{I} - \frac{1}{2}\omega \right)^{-1} -$$ -where $\omega = \frac{1}{2}\left(\boldsymbol{G} - \boldsymbol{G}^{T} \right)$ . -In the code, `total_strain_increment` is `0.5 * (G + G.transpose())` and `rotation_increment` is `Q_1.inverse() * Q_2` . - -## 4. Strain increment in finite strain: how is the incremental deformation gradient F_incr = F_new · F_old⁻¹ computed? - -The incremental deformation gradient, denoted as `_Fhat` in the code, is computed in `ComputeFiniteStrain::computeProperties()` . -The calculation involves: -1. `A = gradU` (current displacement gradient) . -2. `Fbar = gradUold` (old displacement gradient) . -3. `A = gradU - gradUold` . -4. `Fbar = - - -## Eigenstrains and thermal expansion - -MOOSE handles eigenstrains by subtracting them from the total strain to compute the mechanical strain. This is managed through a base class `ComputeEigenstrainBase` and its derived classes, which register eigenstrains that are then collected and subtracted by strain calculator materials like `ComputeStrainBase` . Multiple eigenstrains are combined additively. - -## Classes & Methods - -* `ComputeEigenstrainBaseTempl::computeQpEigenstrain()`: An overridden method in derived eigenstrain classes responsible for calculating and storing the eigenstrain tensor at each quadrature point . -* `ComputeStrainBase::ComputeStrainBase()`: Constructor that retrieves a list of eigenstrain material properties based on user input . -* `ComputeStrainBase::computeProperties()` (or derived classes like `ComputeRSphericalSmallStrain::computeProperties()` ): This method calculates the total strain and then subtracts all registered eigenstrains to determine the mechanical strain. -* `ComputeThermalExpansionEigenstrainTempl::computeThermalStrain()`: Calculates the thermal strain based on the thermal expansion coefficient and temperature difference . -* `ComputeThermalExpansionEigenstrainBaseTempl::computeQpEigenstrain()`: Sets the eigenstrain property based on the computed thermal strain and handles derivatives for Jacobian calculations . - -## Equations - -The mechanical strain ($\boldsymbol{\epsilon}_{mech}$) is computed by subtracting the sum of all eigenstrains ($\boldsymbol{\epsilon}_{eigen}$) from the total strain ($\boldsymbol{\epsilon}_{total}$) . -$$ -\boldsymbol{\epsilon}_{mech} = \boldsymbol{\epsilon}_{total} - \sum_{i} \boldsymbol{\epsilon}_{eigen,i} \quad (1) -$$ -For `ComputeThermalExpansionEigenstrain`, the thermal eigenstrain ($\boldsymbol{\epsilon}^{thermal}$) is calculated as: -$$ -\boldsymbol{\epsilon}^{thermal} = \alpha \cdot \left( T - T_{stress\_free} \right) \boldsymbol{I} \quad (2) -$$ -where $\alpha$ is the thermal expansion coefficient, $T$ is the current temperature, $T_{stress\_free}$ is the stress-free temperature, and $\boldsymbol{I}$ is the identity matrix . - -## Algorithm Steps - -### Eigenstrain Registration and Subtraction - -1. **Define Eigenstrain Material:** Create a material that inherits from `ComputeEigenstrainBase` (e.g., `ComputeThermalExpansionEigenstrain` ). This material will compute a specific eigenstrain tensor. -2. **Register Eigenstrain Name:** In the input file, assign a unique `eigenstrain_name` to each eigenstrain material . -3. **Specify Eigenstrains in Strain Calculator:** In the `ComputeStrainBase` (or derived strain calculator) block, list the `eigenstrain_names` parameter with all the eigenstrains to be considered . -4. **Collect Eigenstrains:** The `ComputeStrainBase` constructor collects pointers to the material properties corresponding to the specified `eigenstrain_names` into the `_eigenstrains` vector . -5. **Compute Total Strain:** The strain calculator computes the total strain based on displacements . -6. **Subtract Eigenstrains:** In the `computeProperties()` method of the strain calculator, each eigenstrain in the `_eigenstrains` vector is subtracted from the `_total_strain` to yield the `_mechanical_strain` . - -` ` `pseudocode -function computeProperties() - for each quadrature point qp - compute _total_strain[qp] from displacements - _mechanical_strain[qp] = _total_strain[qp] - for each eigenstrain es in _eigenstrains - _mechanical_strain[qp] -= (*es)[qp] - end for - end for -end function -` ` ` - -### Temperature-Dependent CTE in `ComputeThermalExpansionEigenstrain` - -1. **Define Thermal Expansion Coefficient:** The `ComputeThermalExpansionEigenstrain` class takes a `thermal_expansion_coeff` parameter . -2. **Compute Thermal Strain:** The `computeThermalStrain()` method calculates the thermal strain using the provided `_thermal_expansion_coeff`, current `_temperature`, and `_stress_free_temperature` . -3. **Store Eigenstrain:** The calculated thermal strain is then stored in the `_eigenstrain` material property by `computeQpEigenstrain()` . - -## Parameters - -* `eigenstrain_names`: (vector of `MaterialPropertyName`) A list of material property names corresponding to the eigenstrain tensors to be subtracted from the total strain . Default is `{}`. -* `thermal_expansion_coeff`: (`Real`) The constant thermal expansion coefficient used by `ComputeThermalExpansionEigenstrain` . -* `stress_free_temperature`: (`Real`) The temperature at which the material is stress-free, used in thermal expansion calculations . -* `temperature`: (`MaterialPropertyName`) The name of the material property providing the current temperature . - -## Relationships - -` ` `mermaid -classDiagram - class Material - class ComputeEigenstrainBaseTempl { - +virtual void computeQpEigenstrain() - #GenericMaterialProperty& _eigenstrain - } - class ComputeThermalExpansionEigenstrainBaseTempl { - +virtual ValueAndDerivative computeThermalStrain() - #const std::vector~ValueAndDerivative~& _temperature - #const VariableValue& _stress_free_temperature - } - class ComputeThermalExpansionEigenstrainTempl { - #const Real& _thermal_expansion_coeff - } - class ComputeStrainBase { - #std::vector~const MaterialProperty~* _eigenstrains - #MaterialProperty~RankTwoTensor~& _mechanical_strain - #MaterialProperty~RankTwoTensor~& _total_strain - } - class ADComputeStrainBaseTempl { - #std::vector~const ADMaterialProperty~* _eigenstrains - #ADMaterialProperty~R2~& _mechanical_strain - #ADMaterialProperty~R2~& _total_strain - } - - Material <|-- ComputeEigenstrainBaseTempl - ComputeEigenstrainBaseTempl <|-- ComputeThermalExpansionEigenstrainBaseTempl - ComputeThermalExpansionEigenstrainBaseTempl <|-- ComputeThermalExpansionEigenstrainTempl - Material <|-- ComputeStrainBase - Material <|-- ADComputeStrainBaseTempl - - ComputeStrainBase "1" *-- "N" ComputeEigenstrainBaseTempl : "collects" - ADComputeStrainBaseTempl "1" *-- "N" ComputeEigenstrainBaseTempl : "collects" -` ` ` - -## MOOSE Input Syntax - -To define two thermal eigenstrains and apply them in a strain calculation: - -` ` `ini -[Materials] - [./elasticity_tensor] - type = ComputeIsotropicElasticityTensor - youngs_modulus = 2.1e5 - poissons_ratio = 0.3 - [../] - [./small_strain] - type = ComputeIncrementalStrain - eigenstrain_names = 'eigenstrain1 eigenstrain2' - [../] - [./thermal_expansion_strain1] - type = ComputeThermalExpansionEigenstrain - stress_free_temperature = 298 - thermal_expansion_coeff = 1.0e-5 - temperature = temp - eigenstrain_name = eigenstrain1 - [../] - [./thermal_expansion_strain2] - type = ComputeThermalExpansionEigenstrain - stress_free_temperature = 298 - thermal_expansion_coeff = 0.3e-5 - temperature = temp - eigenstrain_name = eigenstrain2 - [../] -[] -` ` ` - -## Notes - -### Multiple Eigenstrains - -MOOSE supports multiple eigenstrains, which are combined additively. The `ComputeStrainBase` class (and its Automatic Differentiation counterpart `ADComputeStrainBaseTempl`) stores a vector of pointers to `MaterialProperty` named `_eigenstrains` . During the strain computation, each of these registered eigenstrains is subtracted from the total strain . - -### Finite Strain Formulations - -The provided context primarily focuses on small strain formulations (e.g., `ComputeRSphericalSmallStrain` , `Compute1DSmallStrain` ). While the base classes `ComputeEigenstrainBase` and `ComputeStrainBase` are generic, the specific interaction of eigenstrains with finite strain formulations would depend on the implementation of finite strain calculators, which are not explicitly detailed in the provided snippets. However, the general principle of subtracting eigenstrains from the total strain to get mechanical strain is expected to hold. - -### Stress-Free Strains and Derivatives for Jacobian - -For thermal eigenstrains, the `_stress_free_temperature` is a crucial parameter . The `ComputeThermalExpansionEigenstrainBaseTempl::computeQpEigenstrain()` method also handles the computation of derivatives of the eigenstrain with respect to temperature (`_deigenstrain_dT`) for Jacobian calculations, especially when Automatic Differentiation (AD) is not used directly (`is_ad == false`) . This ensures that the Jacobian matrix, essential for Newton-Raphson solvers, correctly accounts for the influence of eigenstrains. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-stress-computation-chain.md b/packages/akms/src/akms/_bundled/global_nodes/moose-stress-computation-chain.md deleted file mode 100644 index b9ae412..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-stress-computation-chain.md +++ /dev/null @@ -1,296 +0,0 @@ ---- -id: moose-stress-computation-chain -title: MOOSE Constitutive Framework — Stress Update Architecture -domain: constitutive -subdomain: algorithmic -tags: -- stress-update -- compute-stress-base -- inelastic-stress -- material-property -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: medium -reading_priority: full -akms_schema: v2 -edges: -- to: cm-tensor-calculus - type: implements - weight: 0.7 - note: Implements stress tensor computation via MOOSE MaterialProperty system ---- - -# MOOSE Constitutive Framework — Stress Update Architecture - -Framework knowledge node covering 2 aspect(s) of Constitutive Framework — Stress Update Architecture. - -## Stress computation dispatch chain - -The stress computation in MOOSE's Tensor Mechanics module, particularly for inelastic models, follows a hierarchical structure starting from `ComputeStressBase` and extending to specialized inelastic stress computation classes like `ComputeMultipleInelasticStress` and `ComputeCreepPlasticityStress`. Strain input is processed through a series of material properties, and stress output is produced iteratively, especially when multiple inelastic models are involved. - -## 1. How `ComputeStressBase` receives strain input and produces stress output - -`ComputeStressBase` is the foundational class for stress calculations in MOOSE's Solid Mechanics module . It inherits from `ComputeGeneralStressBase` , which defines the core material properties for stress computation. - -**Input:** -`ComputeStressBase` (via `ComputeGeneralStressBase`) receives strain input through the `_mechanical_strain` material property . This property is obtained using `getMaterialPropertyByName(_base_name + "mechanical_strain")` in the constructor of `ComputeGeneralStressBase` . - -**Output:** -The computed stress is stored in the `_stress` material property , which is declared as an output property using `declareProperty(_base_name + "stress")` . Additionally, `_elastic_strain` and `_Jacobian_mult` are also declared and computed. The actual stress computation is performed by the pure virtual function `computeQpStress()` , which must be implemented by derived classes. - -## 2. Role of `ComputeFiniteStrainElasticStress` vs `ComputeMultipleInelasticStress` - -These two classes represent different levels of complexity in stress calculation: - -* **`ComputeFiniteStrainElasticStress`**: This class computes stress based on elasticity theory for finite strains . It directly calculates stress from the elasticity tensor and strain increment, considering finite strain rotations . It does not handle inelastic material behavior directly. - -* **`ComputeMultipleInelasticStress`**: This class, which inherits from `ComputeMultipleInelasticStressBase` , is designed to handle multiple inelastic models (e.g., plasticity, creep) . It orchestrates an iterative process to determine the stress and decompose the strain into elastic and inelastic parts . It uses `StressUpdateBase` derived classes for individual inelastic models . - -In essence, `ComputeFiniteStrainElasticStress` provides a basic elastic stress calculation, while `ComputeMultipleInelasticStress` builds upon this by incorporating and managing complex inelastic material responses through an iterative scheme. - -## 3. How `ComputeMultipleInelasticStress` orchestrates multiple inelastic models - -`ComputeMultipleInelasticStress` (and its base class `ComputeMultipleInelasticStressBase`) orchestrates multiple inelastic models using an iterative Picard scheme . - -**Iteration/Composition Strategy:** - -1. **Initialization**: The `updateQpState` method is called, which initializes `inelastic_strain_increment` for each model to zero . -2. **Iterative Loop**: The class enters a `do-while` loop that continues until the change in stress (`l2norm_delta_stress`) is within user-defined `_absolute_tolerance` and `_relative_tolerance`, or `_max_iterations` is reached . -3. **Model-wise Stress Update**: Inside the loop, it iterates through each registered inelastic model (`_models`) . - * For each model, it sets the current quadrature point (`_qp`) . - * It assumes the strain is initially elastic and subtracts all previously calculated inelastic strain increments from other models . - * A trial stress is formed using the current elasticity tensor and the elastic strain increment . - * The `computeAdmissibleState` method is called for the current inelastic model. This method allows the individual model to produce an admissible stress, and decompose the strain increment into elastic and inelastic parts . -4. **Convergence Check**: After all models have been processed in an iteration, the L2 norm of the change in stress (`l2norm_delta_stress`) is calculated and checked against the tolerances . -5. **Combined Inelastic Strain**: Once convergence is achieved, the `combined_inelastic_strain_increment` is calculated as a weighted sum of the inelastic strain increments from all models . - -A specialized class, `ComputeCreepPlasticityStress`, is designed to combine creep and plasticity models, solving for both simultaneously rather than in a staggered approach . It overrides `updateQpState` to implement its specific coupled iteration strategy . - -## 4. Key MaterialProperty names exchanged - -The following `MaterialProperty` names are crucial for stress computation: - -* `_mechanical_strain`: Represents the total mechanical strain applied to the material . It is an input to the stress calculation. -* `_stress`: The computed stress tensor output by the material model . -* `_elastic_strain`: The elastic portion of the total strain . In inelastic models, this is derived by subtracting inelastic strains from the mechanical strain. -* `_elasticity_tensor`: Represents the material's elasticity tensor, which relates elastic strain to stress . -* `_Jacobian_mult`: Represents the consistent tangent operator, which is the derivative of stress with respect to strain (`dstress_dstrain`) . This is critical for Jacobian computations in the finite element solver. - -## 5. `computeQpStress()` call sequence - -The `computeQpStress()` call sequence starts from the base class and proceeds through the inheritance hierarchy to a specific material model. - -` ` `mermaid -graph TD - A["ComputeGeneralStressBase::computeQpProperties()"] --> B["ComputeGeneralStressBase::computeQpStress() (virtual)"]; - B --> C["ComputeMultipleInelasticStressBase::computeQpStress()"]; - C --> D["ComputeMultipleInelasticStressBase::computeQpStressIntermediateConfiguration()"]; - D --> E["ComputeMultipleInelasticStressBase::updateQpState() (virtual)"]; - E --> F["ComputeMultipleInelasticStress::updateQpState()"]; - F --> G["ComputeMultipleInelasticStressBase::computeAdmissibleState()"]; - G --> H["StressUpdateBase::computeStressTensor() (virtual)"]; -` ` ` - -1. **`ComputeGeneralStressBase::computeQpProperties()`**: This is the entry point for computing material properties at a quadrature point. It calls the virtual `computeQpStress()` method . -2. **`ComputeMultipleInelasticStressBase::computeQpStress()`**: This overridden method handles damage models and finite strain rotations . It calls `computeQpStressIntermediateConfiguration()` . -3. **`ComputeMultipleInelasticStressBase::computeQpStressIntermediateConfiguration()`**: This method prepares for the stress update by initializing `elastic_strain_increment` and `combined_inelastic_strain_increment` . If there are no inelastic models, it performs a simple elastic stress calculation . Otherwise, it calls the virtual `updateQpState()` . -4. **`ComputeMultipleInelasticStress::updateQpState()`**: This is where the iterative process for multiple inelastic models takes place . Within its loop, it calls `computeAdmissibleState()` for each inelastic model . -5. **`ComputeMultipleInelasticStressBase::computeAdmissibleState()`**: This method, implemented in the base class, is responsible for calling the specific `StressUpdateBase` derived model's `computeStressTensor()` method . -6. **`StressUpdateBase::computeStressTensor()`**: This is a virtual method in `StressUpdateBase` that each concrete inelastic model (e.g., `PowerLawCreepStressUpdate`, `IsotropicPlasticityStressUpdate`) must implement to perform its specific stress and inelastic strain calculations. - -For example, in `ComputeCreepPlasticityStress`, the `updateQpState` method is overridden to handle the coupled creep and plasticity calculation . It calls its own `computeStress` method and then iteratively computes inelastic strain increments and updates stress. - -## Classes & Methods - -* `ComputeGeneralStressBase::computeQpProperties()`: The main method called by MOOSE to compute all material properties at a quadrature point. -* `ComputeGeneralStressBase::computeQpStress()`: A pure virtual method that derived classes must implement to calculate the stress tensor. -* `ComputeFiniteStrainElasticStress::computeQpStress()`: Computes stress based on elasticity theory for finite strains. -* `ComputeMultipleInelasticStressBase::computeQpStress()`: Overrides the base `computeQpStress` to handle damage and finite strain rotations, then calls `computeQpStressIntermediateConfiguration`. -* `ComputeMultipleInelasticStressBase::computeQpStressIntermediateConfiguration()`: Computes stress in an intermediate configuration, handling the case of zero inelastic models or calling `updateQpState` for inelastic models. -* `ComputeMultipleInelasticStressBase::updateQpState()`: A pure virtual method for iteratively finding an admissible stress and inelastic strains when multiple inelastic models are present. -* `ComputeMultipleInelasticStress::updateQpState()`: Implements the iterative Picard scheme for combining multiple inelastic models. - - -## Elastic stiffness tensor computation - -# Answer - -You're asking about how MOOSE computes and stores elasticity tensors, specifically covering the `ComputeElasticityTensor` class hierarchy, the `RankFourTensor` data structure, tensor rotation for crystal orientations, and how tensors flow to stress computation. - -## Classes & Methods - - - -**Base Class Hierarchy:** -- `ComputeElasticityTensorBaseTempl` — abstract base for all elasticity tensor computations; declares `_elasticity_tensor` MaterialProperty and pure virtual `computeQpElasticityTensor()` -- `ComputeRotatedElasticityTensorBaseTempl` — intermediate class that adds Euler angle and rotation matrix support -- `ComputeElasticityTensorTempl` — concrete implementation for general anisotropic tensors with symmetry fill methods - -**Key Methods:** -- `ComputeElasticityTensorBaseTempl::computeQpProperties()` — orchestrates tensor computation and applies optional prefactor function -- `ComputeElasticityTensorTempl::computeQpElasticityTensor()` — assigns `_Cijkl` to `_elasticity_tensor[_qp]` -- `RankFourTensor::rotate(RealTensorValue)` — rotates tensor using $C'_{ijkl} = R_{im} R_{jn} R_{ko} R_{lp} C_{mnop}$ - -## Symmetry Class Handling - - - -Symmetry is handled via the `fill_method` parameter passed to `RankFourTensor` constructor: - -- **Isotropic** (`symmetric_isotropic`, `symmetric_isotropic_E_nu`): Detected via `_Cijkl.isIsotropic()` and guaranteed as `ISOTROPIC` -- **Orthotropic/Cubic** (`symmetric9`): 9 independent components; used for cubic crystals and orthotropic materials -- **General Anisotropic** (`symmetric21`): 21 independent components with full symmetries $C_{ijkl} = C_{jikl} = C_{ijlk} = C_{klij}$ -- **Transverse Isotropic** (`axisymmetric_rz`): 5 independent components -- **No Symmetry** (`general`): All 81 components - -The fill method is specified in the input file and determines how the input vector is mapped to the full 3×3×3×3 tensor. - -## RankFourTensor Data Structure - -The codebase context does not contain the `RankFourTensor` header or implementation details. I cannot describe the internal storage layout (e.g., whether it uses a flat array, nested vectors, or sparse representation) or the access patterns without seeing the class definition. To answer this part fully, I would need access to `modules/solid_mechanics/include/materials/RankFourTensor.h` and its implementation. - -What I can confirm is that `RankFourTensor` is instantiated with a vector of Real values and a `FillMethod` enum: - -` ` `cpp -_Cijkl(this->template getParam>("C_ijkl"), - (RankFourTensor::FillMethod)(int)this->template getParam("fill_method")) -` ` ` - -## Rotation of Elasticity Tensor - - - -**For static rotations** (initial setup only): -- `ComputeElasticityTensor` rotates the tensor once during construction -- If `rotation_matrix` parameter is provided, it applies directly: `_Cijkl.rotate(_rotation_matrix)` -- Otherwise, it builds a `RotationTensor` from Euler angles (Bunge convention, $Z_1 X_2 Z_3$ extrinsic) and applies: `_Cijkl.rotate(R)` - -**For dynamic rotations** (crystal plasticity): -- `ComputeElasticityTensorCP` overrides `computeQpElasticityTensor()` to rotate at every timestep -- It uses active rotation (transpose of passive Bunge angles) and updates the rotation matrix from coupled Euler angle variables or a property file -- The rotation is applied as: `_elasticity_tensor[_qp].rotate(_crysrot[_qp])` - -**Rotation Equation:** -$$C'_{ijkl} = R_{im} R_{jn} R_{ko} R_{lp} C_{mnop} \quad (1)$$ - -where $R$ is the rotation matrix (passive convention in `ComputeElasticityTensor`, active in `ComputeElasticityTensorCP`). - -## MaterialProperty Data Flow - - - -The elasticity tensor is declared as a `GenericMaterialProperty` reference: - -` ` `cpp -GenericMaterialProperty & _elasticity_tensor; -` ` ` - -where `T` is either `RankFourTensor` or `SymmetricRankFourTensor`. The property name is stored in `_elasticity_tensor_name` (default: `"elasticity_tensor"` or `"{base_name}_elasticity_tensor"` if a base name is provided). - -**Flow to stress computation:** -1. `ComputeElasticityTensorBase::computeQpProperties()` calls `computeQpElasticityTensor()` -2. Derived classes populate `_elasticity_tensor[_qp]` with the computed tensor -3. Stress materials (e.g., `ComputeLinearElasticStress`) retrieve the property via `getMaterialProperty("elasticity_tensor")` and use it to compute $\sigma_{ij} = C_{ijkl} \epsilon_{kl}$ - -## Parameters - - - -` ` `ini -C_ijkl = > # Required: stiffness tensor components -fill_method = symmetric9 # Optional: symmetry class (default: symmetric9) - # Options: symmetric21, symmetric9, orthotropic, - # symmetric_isotropic, axisymmetric_rz, etc. -euler_angle_1 = 0.0 # Optional: first Euler angle (degrees) -euler_angle_2 = 0.0 # Optional: second Euler angle (degrees) -euler_angle_3 = 0.0 # Optional: third Euler angle (degrees) -rotation_matrix = # Optional: 3×3 rotation matrix (overrides Euler angles) -elasticity_tensor_prefactor = # Optional: scalar multiplier function -base_name = "" # Optional: prefix for material property names -` ` ` - -## Relationships - -` ` `mermaid -graph TD - A["ComputeElasticityTensorBase
(abstract base)"] - B["ComputeRotatedElasticityTensorBase
(adds Euler angles)"] - C["ComputeElasticityTensor
(general anisotropic)"] - D["ComputeIsotropicElasticityTensor
(isotropic only)"] - E["ComputeElasticityTensorCP
(crystal plasticity)"] - F["RankFourTensor
(data structure)"] - G["RotationTensor
(rotation matrix)"] - H["StressCompute
(uses elasticity tensor)"] - - A -->|declares| F - B -->|extends| A - B -->|uses| G - C -->|extends| B - C -->|instantiates| F - D -->|extends| A - E -->|extends| C - E -->|rotates at each step| F - F -->|passed via MaterialProperty| H -` ` ` - -## Code Snippets - -**Constructor with symmetry handling:** - - -**Tensor assignment to MaterialProperty:** - - -**Crystal plasticity dynamic rotation:** - - -## MOOSE Input Syntax - -` ` `ini -[Materials] - [elasticity_tensor] - type = ComputeElasticityTensor - C_ijkl = '1.0 0.5 0.5 1.0 0.5 1.0 0.25 0.25 0.25' - fill_method = symmetric9 - euler_angle_1 = 0.0 - euler_angle_2 = 0.0 - euler_angle_3 = 0.0 - base_name = material1 - [] -[] -` ` ` - -For isotropic materials: -` ` `ini -[Materials] - [elasticity_tensor] - type = ComputeIsotropicElasticityTensor - youngs_modulus = 210e9 - poissons_ratio = 0.3 - [] -[] -` ` ` - -For crystal plasticity with dynamic rotation: -` ` `ini -[Materials] - [elasticity_tensor] - type = ComputeElasticityTensorCP - C_ijkl = '1.0 0.5 0.5 1.0 0.5 1.0 0.25 0.25 0.25' - fill_method = symmetric9 - euler_angle_variables = 'euler_1 euler_2 euler_3' - [] -[] -` ` ` - -## Notes - -The codebase context does not include the `RankFourTensor` class definition, so I cannot provide details on its internal storage layout or element access patterns. The documentation references engineering notation (6×6 matrix) and Einstein index notation (4-index), but the actual 3×3×3×3 storage mechanism is not visible in the provided snippets. - -`ComputeElasticityTensorCP` differs from `ComputeElasticityTensor` in two key ways: (1) it uses **active** rotation (transpose of Bunge angles) rather than passive, and (2) it rotates the tensor at every material timestep, not just during initialization. This is critical for crystal plasticity simulations where the crystal frame evolves with plastic deformation. - -The `_elasticity_tensor` MaterialProperty is templated on `is_ad` (automatic differentiation flag), allowing both regular and AD-enabled stress computations to use the same material class. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-stress-dispatch-chain.md b/packages/akms/src/akms/_bundled/global_nodes/moose-stress-dispatch-chain.md deleted file mode 100644 index 35261dd..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-stress-dispatch-chain.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: moose-stress-dispatch-chain -title: MOOSE Stress computation dispatch chain -domain: constitutive -subdomain: algorithmic -tags: -- stress-update -- compute-stress-base -- compute-multiple-inelastic-stress -- material-property -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-stress-computation-chain - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-stress-computation-chain -- to: cm-tensor-calculus - type: implements - weight: 0.7 - note: Stress computation chain for tensor mechanics ---- - -# MOOSE Stress computation dispatch chain - -The stress computation in MOOSE's Tensor Mechanics module, particularly for inelastic models, follows a hierarchical structure starting from `ComputeStressBase` and extending to specialized inelastic stress computation classes like `ComputeMultipleInelasticStress` and `ComputeCreepPlasticityStress`. Strain input is processed through a series of material properties, and stress output is produced iteratively, especially when multiple inelastic models are involved. - -## 1. How `ComputeStressBase` receives strain input and produces stress output - -`ComputeStressBase` is the foundational class for stress calculations in MOOSE's Solid Mechanics module . It inherits from `ComputeGeneralStressBase` , which defines the core material properties for stress computation. - -**Input:** -`ComputeStressBase` (via `ComputeGeneralStressBase`) receives strain input through the `_mechanical_strain` material property . This property is obtained using `getMaterialPropertyByName(_base_name + "mechanical_strain")` in the constructor of `ComputeGeneralStressBase` . - -**Output:** -The computed stress is stored in the `_stress` material property , which is declared as an output property using `declareProperty(_base_name + "stress")` . Additionally, `_elastic_strain` and `_Jacobian_mult` are also declared and computed. The actual stress computation is performed by the pure virtual function `computeQpStress()` , which must be implemented by derived classes. - -## 2. Role of `ComputeFiniteStrainElasticStress` vs `ComputeMultipleInelasticStress` - -These two classes represent different levels of complexity in stress calculation: - -* **`ComputeFiniteStrainElasticStress`**: This class computes stress based on elasticity theory for finite strains . It directly calculates stress from the elasticity tensor and strain increment, considering finite strain rotations . It does not handle inelastic material behavior directly. - -* **`ComputeMultipleInelasticStress`**: This class, which inherits from `ComputeMultipleInelasticStressBase` , is designed to handle multiple inelastic models (e.g., plasticity, creep) . It orchestrates an iterative process to determine the stress and decompose the strain into elastic and inelastic parts . It uses `StressUpdateBase` derived classes for individual inelastic models . - -In essence, `ComputeFiniteStrainElasticStress` provides a basic elastic stress calculation, while `ComputeMultipleInelasticStress` builds upon this by incorporating and managing complex inelastic material responses through an iterative scheme. - -## 3. How `ComputeMultipleInelasticStress` orchestrates multiple inelastic models - -`ComputeMultipleInelasticStress` (and its base class `ComputeMultipleInelasticStressBase`) orchestrates multiple inelastic models using an iterative Picard scheme . - -**Iteration/Composition Strategy:** - -1. **Initialization**: The `updateQpState` method is called, which initializes `inelastic_strain_increment` for each model to zero . -2. **Iterative Loop**: The class enters a `do-while` loop that continues until the change in stress (`l2norm_delta_stress`) is within user-defined `_absolute_tolerance` and `_relative_tolerance`, or `_max_iterations` is reached . -3. **Model-wise Stress Update**: Inside the loop, it iterates through each registered inelastic model (`_models`) . - * For each model, it sets the current quadrature point (`_qp`) . - * It assumes the strain is initially elastic and subtracts all previously calculated inelastic strain increments from other models . - * A trial stress is formed using the current elasticity tensor and the elastic strain increment . - * The `computeAdmissibleState` method is called for the current inelastic model. This method allows the individual model to produce an admissible stress, and decompose the strain increment into elastic and inelastic parts . -4. **Convergence Check**: After all models have been processed in an iteration, the L2 norm of the change in stress (`l2norm_delta_stress`) is calculated and checked against the tolerances . -5. **Combined Inelastic Strain**: Once convergence is achieved, the `combined_inelastic_strain_increment` is calculated as a weighted sum of the inelastic strain increments from all models . - -A specialized class, `ComputeCreepPlasticityStress`, is designed to combine creep and plasticity models, solving for both simultaneously rather than in a staggered approach . It overrides `updateQpState` to implement its specific coupled iteration strategy . - -## 4. Key MaterialProperty names exchanged - -The following `MaterialProperty` names are crucial for stress computation: - -* `_mechanical_strain`: Represents the total mechanical strain applied to the material . It is an input to the stress calculation. -* `_stress`: The computed stress tensor output by the material model . -* `_elastic_strain`: The elastic portion of the total strain . In inelastic models, this is derived by subtracting inelastic strains from the mechanical strain. -* `_elasticity_tensor`: Represents the material's elasticity tensor, which relates elastic strain to stress . -* `_Jacobian_mult`: Represents the consistent tangent operator, which is the derivative of stress with respect to strain (`dstress_dstrain`) . This is critical for Jacobian computations in the finite element solver. - -## 5. `computeQpStress()` call sequence - -The `computeQpStress()` call sequence starts from the base class and proceeds through the inheritance hierarchy to a specific material model. - -` ` `mermaid -graph TD - A["ComputeGeneralStressBase::computeQpProperties()"] --> B["ComputeGeneralStressBase::computeQpStress() (virtual)"]; - B --> C["ComputeMultipleInelasticStressBase::computeQpStress()"]; - C --> D["ComputeMultipleInelasticStressBase::computeQpStressIntermediateConfiguration()"]; - D --> E["ComputeMultipleInelasticStressBase::updateQpState() (virtual)"]; - E --> F["ComputeMultipleInelasticStress::updateQpState()"]; - F --> G["ComputeMultipleInelasticStressBase::computeAdmissibleState()"]; - G --> H["StressUpdateBase::computeStressTensor() (virtual)"]; -` ` ` - -1. **`ComputeGeneralStressBase::computeQpProperties()`**: This is the entry point for computing material properties at a quadrature point. It calls the virtual `computeQpStress()` method . -2. **`ComputeMultipleInelasticStressBase::computeQpStress()`**: This overridden method handles damage models and finite strain rotations . It calls `computeQpStressIntermediateConfiguration()` . -3. **`ComputeMultipleInelasticStressBase::computeQpStressIntermediateConfiguration()`**: This method prepares for the stress update by initializing `elastic_strain_increment` and `combined_inelastic_strain_increment` . If there are no inelastic models, it performs a simple elastic stress calculation . Otherwise, it calls the virtual `updateQpState()` . -4. **`ComputeMultipleInelasticStress::updateQpState()`**: This is where the iterative process for multiple inelastic models takes place . Within its loop, it calls `computeAdmissibleState()` for each inelastic model . -5. **`ComputeMultipleInelasticStressBase::computeAdmissibleState()`**: This method, implemented in the base class, is responsible for calling the specific `StressUpdateBase` derived model's `computeStressTensor()` method . -6. **`StressUpdateBase::computeStressTensor()`**: This is a virtual method in `StressUpdateBase` that each concrete inelastic model (e.g., `PowerLawCreepStressUpdate`, `IsotropicPlasticityStressUpdate`) must implement to perform its specific stress and inelastic strain calculations. - -For example, in `ComputeCreepPlasticityStress`, the `updateQpState` method is overridden to handle the coupled creep and plasticity calculation . It calls its own `computeStress` method and then iteratively computes inelastic strain increments and updates stress. - -## Classes & Methods - -* `ComputeGeneralStressBase::computeQpProperties()`: The main method called by MOOSE to compute all material properties at a quadrature point. -* `ComputeGeneralStressBase::computeQpStress()`: A pure virtual method that derived classes must implement to calculate the stress tensor. -* `ComputeFiniteStrainElasticStress::computeQpStress()`: Computes stress based on elasticity theory for finite strains. -* `ComputeMultipleInelasticStressBase::computeQpStress()`: Overrides the base `computeQpStress` to handle damage and finite strain rotations, then calls `computeQpStressIntermediateConfiguration`. -* `ComputeMultipleInelasticStressBase::computeQpStressIntermediateConfiguration()`: Computes stress in an intermediate configuration, handling the case of zero inelastic models or calling `updateQpState` for inelastic models. -* `ComputeMultipleInelasticStressBase::updateQpState()`: A pure virtual method for iteratively finding an admissible stress and inelastic strains when multiple inelastic models are present. -* `ComputeMultipleInelasticStress::updateQpState()`: Implements the iterative Picard scheme for combining multiple inelastic models. - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-stress-measures.md b/packages/akms/src/akms/_bundled/global_nodes/moose-stress-measures.md deleted file mode 100644 index 3ce7233..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-stress-measures.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -id: moose-stress-measures -title: MOOSE Stress measures and conversions in MOOSE -domain: constitutive -subdomain: algorithmic -tags: -- cauchy-stress -- piola-kirchhoff -- kirchhoff-stress -- mandel-stress -- green-lagrange -- hencky-strain -- almansi -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-objectivity-frame-operations - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-objectivity-frame-operations ---- - -# MOOSE Stress measures and conversions in MOOSE - -MOOSE's Solid Mechanics module computes and converts between several stress and strain measures, primarily focusing on Cauchy stress, 1st Piola-Kirchhoff (PK1) stress, and 2nd Piola-Kirchhoff (PK2) stress, along with Green-Lagrange strain. The conversions are handled within a hierarchy of material classes, specifically `ComputeLagrangianStressBase` and its derivatives, which implement the necessary transformations based on whether large or small deformation kinematics are used . - -## Stress Measures and Conversions - -### 1. Cauchy stress $\sigma$ (true stress) -The Cauchy stress is a primary output in MOOSE, particularly when using classes derived from `ComputeLagrangianStressCauchy` . It is stored as a `MaterialProperty` named `_cauchy_stress` . - -#### Conversion from 1st Piola-Kirchhoff stress to Cauchy stress -When `_large_kinematics` is true, the Cauchy stress is computed from PK1 stress using the deformation gradient $F$ and its determinant $J$ (which is `_F[_qp].det()`): -$$ -\sigma = \frac{1}{J} P F^T \quad (1) -$$ -This conversion is implemented in `ComputeLagrangianStressPK1::computeQpCauchyStress()` . For small deformations, Cauchy stress is considered equivalent to PK1 stress . - -### 2. 1st Piola-Kirchhoff stress $P$ -The 1st Piola-Kirchhoff stress is also a primary output, especially for total Lagrangian formulations . It is stored as `_pk1_stress` . - -#### Conversion from Cauchy stress to 1st Piola-Kirchhoff stress -When `_large_kinematics` is true, PK1 stress is computed from Cauchy stress using the deformation gradient $F$ and its inverse $F^{-1}$ (represented by `_inv_def_grad`) and determinant $J$: -$$ -P = J \sigma F^{-T} \quad (2) -$$ -This conversion is implemented in `ComputeLagrangianStressCauchy::computeQpPK1Stress()` . For small deformations, PK1 stress is considered equivalent to Cauchy stress . - -#### Conversion from 2nd Piola-Kirchhoff stress to 1st Piola-Kirchhoff stress -When `_large_kinematics` is true, PK1 stress is computed from PK2 stress using the deformation gradient $F$: -$$ -P = F S \quad (3) -$$ -This conversion is implemented in `ComputeLagrangianStressPK2::computeQpPK1Stress()` . For small deformations, PK1 stress is considered equivalent to PK2 stress . - -### 3. 2nd Piola-Kirchhoff stress $S$ -The 2nd Piola-Kirchhoff stress is used for total Lagrangian formulations and is stored as `_S` . Classes like `ComputeNeoHookeanStress` and `ComputeStVenantKirchhoffStress` directly compute PK2 stress. - -### 4. Kirchhoff stress $\tau = J \sigma$ -The Kirchhoff stress is mentioned in the context of Simo-Hughes J2 plasticity . While not explicitly stored as a `MaterialProperty`, it is computed within the `ComputeSimoHughesJ2PlasticityStress` class . - -### 5. Mandel stress $M_e = C^e S^e = F^{eT} \tau F^{e-T}$ -The Mandel stress is not directly computed or stored as a `MaterialProperty` in the provided context. However, `MandelConverter` is included in `ComputeLagrangianObjectiveCustomStress.h` , suggesting its potential use for conversions related to custom material models. - -## Strain Measures - -### 6. Green-Lagrange strain $E = \frac{1}{2}(F^T F - I)$ -MOOSE computes the Green-Lagrange strain. It is explicitly calculated in `ComputeLagrangianStressPK2::computeQpPK1Stress()` and stored as `_E` . `ADComputeGreenLagrangeStrain` is a dedicated class for defining this strain tensor . The Almansi strain is not explicitly mentioned as being computed. - -### 7. Logarithmic (Hencky) strain: $\ln(U)$ -Logarithmic strain is available in MOOSE. It is referred to as "mechanical_strain" and represents the integrated deformation rate . It is used as an input to stress computation classes like `ComputeLagrangianObjectiveStress` . - -## Conversion Handling - -Conversions between stress measures are handled through a hierarchy of material classes, primarily `ComputeLagrangianStressBase` and its derived classes (`ComputeLagrangianStressCauchy`, `ComputeLagrangianStressPK1`, `ComputeLagrangianStressPK2`). These classes define virtual methods for computing specific stress measures and then wrap these to provide other required stress forms . The conversions are performed "ad-hoc" within these material models, often with conditional logic based on the `_large_kinematics` flag to switch between large and small deformation formulations . - -### Classes & Methods: - -* `ComputeLagrangianStressBase` : Base class for Lagrangian stress computations, defining the interface for Cauchy and 1st PK stress and their Jacobians . - * `computeQpStressUpdate()`: Virtual method to be implemented by derived classes for stress updates . -* `ComputeLagrangianStressCauchy` : Implements Cauchy stress update and wraps it to provide 1st PK stress . - * `computeQpPK1Stress()`: Converts Cauchy stress to 1st PK stress . -* `ComputeLagrangianStressPK1` : Implements 1st PK stress update and wraps it to provide Cauchy stress . - * `computeQpCauchyStress()`: Converts 1st PK stress to Cauchy stress . -* `ComputeLagrangianStressPK2` : Implements 2nd PK stress update and wraps it to provide 1st PK stress . - * `computeQpPK1Stress()`: Converts 2nd PK stress to 1st PK stress and computes Green-Lagrange strain . -* `ADComputeGreenLagrangeStrain` : Defines the Green-Lagrange strain tensor . -* `ComputeSimoHughesJ2PlasticityStress` : Computes Kirchhoff stress as part of its algorithm . - -### Relationships: - -` ` `mermaid -classDiagram - class Material - class ComputeLagrangianStressBase - class ComputeLagrangianStressCauchy - class ComputeLagrangianStressPK1 - class ComputeLagrangianStressPK2 - class ComputeLagrangianObjectiveStress - class ComputeNeoHookeanStress - class ComputeStVenantKirchhoffStress - class ComputeSimoHughesJ2PlasticityStress - class ADComputeGreenLagrangeStrain - - Material <|-- ComputeLagrangianStressBase - ComputeLagrangianStressBase <|-- ComputeLagrangianStressCauchy - ComputeLagrangianStressBase <|-- ComputeLagrangianStressPK1 - ComputeLagrangianStressPK1 <|-- ComputeLagrangianStressPK2 - ComputeLagrangianStressCauchy <|-- ComputeLagrangianObjectiveStress - ComputeLagrangianStressPK2 <|-- ComputeNeoHookeanStress - ComputeLagrangianStressPK2 <|-- ComputeStVenantKirchhoffStress - ComputeLagrangianStressPK1 <|-- ComputeSimoHughesJ2PlasticityStress - - ComputeLagrangianStressBase : +_cauchy_stress - ComputeLagrangianStressBase : +_pk1_stress - ComputeLagrangianStressPK2 : +_E (Green-Lagrange strain) - ComputeLagrangianStressPK2 : +_S (2nd PK stress) - ComputeLagrangianStressBase : +_large_kinematics - ComputeLagrangianStressBase : +computeQpStressUpdate() - ComputeLagrangianStressCauchy : +computeQpPK1Stress() - ComputeLagrangianStressPK1 : +computeQpCauchyStress() - ComputeLagrangianStressPK2 : +computeQpPK1Stress() - ComputeLagrangianStressPK2 : + - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-system-taxonomy.md b/packages/akms/src/akms/_bundled/global_nodes/moose-system-taxonomy.md deleted file mode 100644 index eafe112..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-system-taxonomy.md +++ /dev/null @@ -1,256 +0,0 @@ ---- -id: moose-system-taxonomy -title: MOOSE MOOSE class hierarchy and system taxonomy -domain: architecture -subdomain: procedural -tags: -- kernel -- material -- boundary-condition -- aux-kernel -- user-object -- DG-kernel -- interface-kernel -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-object-factory - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-object-factory ---- - -# MOOSE MOOSE class hierarchy and system taxonomy - -This response outlines the core systems in MOOSE as requested, detailing their base classes, essential virtual methods to override, and typical execution patterns. - -## 1. Kernel — Volume Integrals (Weak Form Terms) - -**Base Class:** The primary base class for Kernels is `Kernel` . For automatic differentiation (AD) enabled Kernels, the base class is `ADKernel` . Both inherit from `KernelBase` . - -**Classes & Methods:** -* `Kernel::computeQpResidual()`: Computes the Kernel's contribution to the residual at a quadrature point. This method *must* be overridden . -* `Kernel::computeQpJacobian()`: Computes the Kernel's contribution to the diagonal Jacobian entries at a quadrature point . -* `Kernel::computeQpOffDiagJacobian(unsigned int jvar)`: Computes the off-diagonal Jacobian entries for coupling with other variables . - -**Execution Pattern:** -Kernels are responsible for computing terms in the weak form of a PDE. The `computeQpResidual()` method is called for each quadrature point within an element to calculate the residual contribution . Optionally, `computeQpJacobian()` and `computeQpOffDiagJacobian()` can be overridden to provide Jacobian contributions, which aid in solver convergence . These methods have access to various member variables like `_u` (variable value), `_grad_u` (variable gradient), `_test` (test function), and `_grad_test` (test function gradient) at the current quadrature point . - -**Code Snippets:** -` ` `cpp -// From framework/include/kernels/Kernel.h -protected: - /** - * Compute this Kernel's contribution to the residual at the current quadrature point - */ - virtual Real computeQpResidual() = 0; - - /** - * Compute this Kernel's contribution to the Jacobian at the current quadrature point - */ - virtual Real computeQpJacobian() { return 0; } - - /** - * For coupling standard variables - */ - virtual Real computeQpOffDiagJacobian(unsigned int /*jvar*/) { return 0; } -` ` ` -` ` `cpp -// From test/src/kernels/DiffMKernel.C -Real -DiffMKernel::computeQpResidual() -{ - return _diff[_qp] * _grad_test[_i][_qp] * _grad_u[_qp] - _offset; -} - -Real -DiffMKernel::computeQpJacobian() -{ - return _diff[_qp] * _grad_test[_i][_qp] * _grad_phi[_j][_qp]; -} -` ` ` - -## 2. BoundaryCondition — DirichletBC, NeumannBC, IntegratedBC - -**Base Class:** The base class for boundary conditions is `BoundaryCondition` . Integrated boundary conditions derive from `IntegratedBCBase` , while Dirichlet boundary conditions typically derive from `DirichletBCBase` . - -**Classes & Methods:** -* `IntegratedBCBase::computeQpResidual()`: (Implicitly, through `BoundaryCondition` and its derivatives) Computes the residual contribution from the boundary condition at a quadrature point. -* `IntegratedBCBase::computeQpJacobian()`: (Implicitly) Computes the Jacobian contribution from the boundary condition at a quadrature point. - -**Execution Pattern:** -Boundary conditions contribute to the residual and Jacobian on the boundaries of the domain. For `IntegratedBCBase` objects, the `computeQpResidual()` and `computeQpJacobian()` methods are called for quadrature points on the boundary faces of elements . These methods have access to boundary-specific data such as `_current_side`, `_current_side_volume`, and `_current_boundary_id` . - -**Code Snippets:** -` ` `cpp -// From framework/include/bcs/IntegratedBCBase.h -class IntegratedBCBase : public BoundaryCondition, - public CoupleableMooseVariableDependencyIntermediateInterface, - public MaterialPropertyInterface -{ -public: - static InputParameters validParams(); - - IntegratedBCBase(const InputParameters & parameters); - - void prepareShapes(unsigned int var_num) override final; - - virtual bool shouldApply() const override; - -protected: - /// current element - const Elem * const & _current_elem; - /// Volume of the current element - const Real & _current_elem_volume; - /// current side of the current element - const unsigned int & _current_side; - /// current side element - const Elem * const & _current_side_elem; - /// Volume of the current side - const Real & _current_side_volume; - /// The currenty boundary id - const BoundaryID & _current_boundary_id; - - /// quadrature point index - unsigned int _qp; - /// active quadrature rule - const QBase * const & _qrule; - /// active quadrature points - const MooseArray & _q_point; - /// transformed Jacobian weights - const MooseArray & _JxW; - /// coordinate transformation - const MooseArray & _coord; - /// i-th, j-th index for enumerating test and shape functions - unsigned int _i, _j; -` ` ` - -## 3. Material — MaterialProperty Computation - -**Base Class:** The base class for materials is `MaterialBase` . - -**Classes & Methods:** -* `MaterialBase::computeProperties()`: This pure virtual method *must* be overridden to compute material properties . -* `MaterialBase::initStatefulProperties(const unsigned int n_points)`: Initializes stateful properties . - -**Execution Pattern:** -Material objects compute spatially and/or temporally varying properties, which are typically indexed at individual quadrature points . The `computeProperties()` method is invoked to calculate these properties, which can then be accessed by other MOOSE systems like Kernels and Boundary Conditions . Materials can also declare and consume properties from other materials or variables . - -**Code Snippets:** -` ` `cpp -// From framework/include/materials/MaterialBase.h -class MaterialBase : public MooseObject, - public BlockRestrictable, - public BoundaryRestrictable, - public SetupInterface, - public MooseVariableDependencyInterface, - public ScalarCoupleable, - public FunctionInterface, - public DistributionInterface, - public UserObjectInterface, - public TransientInterface, - public PostprocessorInterface, - public VectorPostprocessorInterface, - public DependencyResolverInterface, - public Restartable, - public MeshChangedInterface, - public OutputInterface, - public RandomInterface, - public ElementIDInterface, - protected GeometricSearchInterface, - protected ADFunctorInterface -{ -public: - static InputParameters validParams(); - - MaterialBase(const InputParameters & parameters); - -#ifdef MOOSE_KOKKOS_ENABLED - /** - * Special constructor used for Kokkos functor copy during parallel dispatch - */ - MaterialBase(const MaterialBase & object, const Moose::Kokkos::FunctorCopy & key); -#endif - - /** - * Initialize stateful properties (if material has some) - * - * This is _only_ called if this material has properties that are - * requested as stateful - */ - virtual void initStatefulProperties(const unsigned int n_points); - - virtual bool isInterfaceMaterial() { return false; }; - - /** - * Performs the quadrature point loop, calling computeQpProperties - */ - virtual void computeProperties() = 0; -` ` ` - -## 4. AuxKernel — Auxiliary Variable Computation - -**Base Class:** The base class for auxiliary kernels is `AuxKernelTempl` , which inherits from `AuxKernelBase` . `AuxKernel` is a typedef for `AuxKernelTempl` . - -**Classes & Methods:** -* `AuxKernelTempl::computeValue()`: This pure virtual method *must* be overridden to compute the value of the auxiliary variable . -* `AuxKernelTempl::compute()`: Computes the value and stores it in the solution vector . - -**Execution Pattern:** -AuxKernels compute and set explicitly known values of auxiliary variables . Unlike Kernels, AuxKernels do not compute residuals and do not involve test functions . The `computeValue()` method is called to determine the value of the auxiliary variable, which is then inserted into the auxiliary solution vector . AuxKernels can operate on elemental or nodal auxiliary variables . - -**Code Snippets:** -` ` `cpp -// From framework/include/auxkernels/AuxKernel.h -protected: - /** - * Compute and return the value of the aux variable. - */ - virtual ComputeValueType computeValue() = 0; -` ` ` -` ` `cpp -// From framework/include/auxkernels/AuxKernel.h - /** - * Computes the value and stores it in the solution vector - */ - virtual void compute() override; -` ` ` - -## 5. UserObject — General Computation Objects (Postprocessors, VectorPostprocessors) - -**Base Class:** The base class for UserObjects is `UserObject` . - -**Classes & Methods:** -* `UserObject::execute()`: Performs the main computation of the UserObject. -* `UserObject::getValue()`: Returns the computed value of the UserObject. - -**Execution Pattern:** -UserObjects are general computation objects that can perform various tasks. They are often used for post-processing, data analysis, or to provide values to other MOOSE objects . The `execute()` method is called at different times depending on the type of UserObject (e.g., `GeneralPostprocessor`, `NodalPostprocessor`, `ElementalPostprocessor`) and the configured execution flags . The `getValue()` method is responsible for returning the result of the computation . - -## 6. Constraint — Nodal/Mortar Constraints - -**Base Class:** The base class for constraints is `Constraint` . Specific types include `NodalConstraint` and `MortarConstraint` . - -**Classes & Methods:** -* `Constraint::constrain()`: Applies the constraint to the system. - -**Execution Pattern:** -Constraints are used to enforce relationships between degrees of freedom, such as nodal constraints or mortar constraints for non-conforming meshes. They modify the system's residual and Jacobian to impose these conditions. The `constrain()` method is typically called during the assembly process to apply the constraint equations. - -## 7. DGKernel — Discontinuous Galerkin - -**Base Class:** The base class for Discontinuous Galerkin (DG) Kernels is `DGKernelBase` . - -**Classes & Methods:** -* `DGKernelBase::computeQpResidual()`: Computes the residual contribution for DG terms at a quadrature point. -* `DGKernelBase::computeQpJacobian()`: Computes the Jacobian contribution for DG terms at a quadrature point. - -Wiki pages you might want to explore: -- [Problem Solving Architecture (idaholab/moose)](https://deepwiki.com/idaholab/moose#3) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-threaded-assembly.md b/packages/akms/src/akms/_bundled/global_nodes/moose-threaded-assembly.md deleted file mode 100644 index a114347..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-threaded-assembly.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -id: moose-threaded-assembly -title: MOOSE Thread-level parallelism and assembly loop -domain: architecture -subdomain: algorithmic -tags: -- threading -- element-loop -- quadrature -- assembly -- AD-kernel -- reinit -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-assembly-loop - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-assembly-loop -- to: tgs-dom-fem - type: implements - weight: 0.7 - note: Threaded FEM assembly with AD support ---- - -# MOOSE Thread-level parallelism and assembly loop - -The user is asking for a detailed explanation of MOOSE's execution architecture, focusing on the assembly process. This involves understanding the call chain from `Executioner` to `ThreadedElementLoop`, the threading model, the role of per-thread `Assembly` objects, the element loop's operations, quadrature, variable coupling, automatic differentiation, and object execution ordering. - -I will address each point of your query by referencing relevant classes, methods, and concepts within the MOOSE framework. - -## Execution Architecture Overview - -MOOSE's execution architecture is centered around solving finite element problems. The `Executioner` class orchestrates the overall simulation, which typically involves a `NonlinearSystem` to handle the nonlinear solve, and an `FEProblem` that manages the finite element discretization and assembly process. The core of the assembly happens within `ThreadedElementLoop` and its derived classes, which parallelize the element-wise computations. - -### 1. `Executioner` → `NonlinearSystem` → `FEProblem` → `ThreadedElementLoop` Call Chain - -The simulation begins with an `Executioner` object, which defines the `execute()` interface for running simulations . Different types of executioners exist, such as `Steady` and `Transient`, for various simulation types . - -Within the `Executioner`, the `FEProblemSolve` object encapsulates the logic for solving the `FEProblem` . The `FEProblem` then interacts with one or more `NonlinearSystem` objects to manage the solution variables and their associated equations . - -The `NonlinearSystemBase` class is responsible for the assembly of residuals and Jacobians . This assembly process is parallelized using `ThreadedElementLoop` and its specialized derived classes, such as `NonlinearThread` . - -The call chain for assembly generally follows: -`Executioner::execute()` → `FEProblemSolve::solve()` → `FEProblem::computeResidual()` / `FEProblem::computeJacobian()` → `NonlinearSystemBase::assemble()` → `ThreadedElementLoop::operator()` . - -### 2. Threading Model: TBB or pthreads — How are element ranges split across threads? - -MOOSE leverages `libMesh` for its threading capabilities, which can utilize either TBB (Threading Building Blocks) or pthreads. The `ThreadedElementLoop` class is the base for parallelizing operations over elements . - -The `operator()` method of `ThreadedElementLoop` takes a `ConstElemRange` as input, which represents a range of elements to be processed . This range is split across available threads. Each thread then iterates over its assigned subset of elements, performing computations such as `onElement()`, `onBoundary()`, and `onInternalSide()` . The `libMesh::n_threads()` function returns the number of active threads . - -### 3. Per-thread `Assembly` objects: why one per thread? How do they avoid data races? - -MOOSE uses per-thread `Assembly` objects to avoid data races during the element assembly process . Each thread has its own `Assembly` object, which manages local data structures like `_local_re` (local residual) and `_local_ke` (local Jacobian) . - -By having a separate `Assembly` object for each thread, computations on different elements can proceed concurrently without contention for shared memory. After each thread completes its local assembly for its assigned elements, the local contributions are accumulated into the global PETSc `Mat` (matrix) and `Vec` (vector) in a thread-safe manner . This accumulation typically involves atomic operations or critical sections to ensure data integrity when updating the global sparse matrix and vector. - -### 4. The element loop: `reinit(elem)` → compute kernels → accumulate `_local_re`/`_local_ke` → add to global PETSc Mat/Vec - -The element loop, as implemented in `ThreadedElementLoop` and its derivatives like `NonlinearThread`, follows a specific sequence for each element: -1. **`reinit(elem)`**: Before processing an element, the finite element data (shape functions, Jacobians, etc.) and material properties are reinitialized for the current element. This is handled by methods like `FEProblemBase::reinitElement()` and `FEProblemBase::reinitMaterials()` . The `MooseVariableFE` objects also reinitialize their data for the current element . -2. **Compute Kernels**: The `computeOnElement()` method (or similar for boundaries/interfaces) is called, which iterates through the registered `Kernel` objects. Each `Kernel` then computes its contribution to the residual and Jacobian for the current element at each quadrature point . For example, `Kernel::computeResidual()` and `Kernel::computeJacobian()` are called . -3. **Accumulate `_local_re`/`_local_ke`**: Inside the kernel's `computeResidual()` and `computeJacobian()` methods, the contributions are added to the thread-local `_local_re` (residual vector) and `_local_ke` (Jacobian matrix) . -4. **Add to global PETSc Mat/Vec**: After all kernels have computed their contributions for an element, the `accumulate()` method (or similar) is called to add the thread-local `_local_re` and `_local_ke` to the global PETSc `Mat` and `Vec` . This is typically done using `add_vector()` and `add_matrix()` methods on the PETSc objects. - -### 5. Quadrature: `_qp` index, `_JxW[_qp]`, `_test[_i][_qp]`, `_phi[_j][_qp]` — how are shape function values cached? - -Quadrature is fundamental to numerical integration in finite element methods . MOOSE uses Gaussian quadrature to approximate integrals over elements. -- `_qp`: This is the current quadrature point index within the element . -- `_JxW[_qp]`: This array stores the product of the Jacobian determinant of the mapping from reference to physical element and the quadrature weight at each quadrature point . MOOSE automatically handles this term, so kernels only compute the integrand . -- `_test[_i][_qp]`: This represents the value of the `i`-th test function at the `_qp`-th quadrature point . -- `_phi[_j][_qp]`: This represents the value of the `j`-th trial function (shape function) at the `_qp`-th quadrature point . - -Shape function values and their gradients (`_grad_test`, `_grad_phi`) are precomputed and cached by the `Assembly` object for the current element and quadrature rule . This caching avoids redundant computations within the inner loops of kernels. The `MooseVariableData` class, which is associated with each `MooseVariableFE`, holds pointers to assembly methods that retrieve these precomputed values . - -### 6. Variable coupling: on-diagonal vs off-diagonal Jacobian blocks — how determined? - -Variable coupling determines which entries in the Jacobian matrix are non-zero. -- **On-diagonal Jacobian blocks**: These represent the derivative of a residual with respect to its own primary variable. For a `Kernel` operating on variable `u`, `computeQpJacobian()` calculates $\frac{\partial R_u}{\partial u}$ . -- **Off-diagonal Jacobian blocks**: These represent the derivative of a residual with respect to a *coupled* variable. For a `Kernel` operating on variable `u` that is coupled to variable `v`, `computeQpOffDiagJacobian(jvar_num)` calculates $\frac{\partial R_u}{\partial v}$ . The `jvar_num` argument specifies the coupled variable's number. - -The `FEProblem` maintains a list of coupled variables for each system. When a `Kernel` is created, it declares its dependencies on other variables. During assembly, the `NonlinearSystemBase` uses this coupling information to determine which `computeQpOffDiagJacobian()` methods need to be called . If a variable is not explicitly coupled, its off-diagonal Jacobian contribution is assumed to be zero. - -### 7. AD (automatic differentiation) path: `ADKernel` and `DualNumber` types — how does AD change the assembly? - -MOOSE supports Automatic Differentiation (AD) to compute Jacobians analytically, which can improve accuracy and performance compared to finite differencing. -- `ADKernel`: This is a specialized `Kernel` class designed to work with AD . -- `DualNumber` types: MOOSE uses `ADReal` (a `DualNumber` type) to represent values and their derivatives. When AD is enabled, variables and intermediate computations within kernels are performed using `ADReal` instead of `Real`. - -When AD is used, the `computeQpResidual()` method in an `ADKernel` returns an `ADReal` value, which implicitly carries the derivative information with respect to all dependent variables . This means that the `computeQpJacobian()` and `computeQpOffDiagJacobian()` methods do not need to be explicitly overridden by the user for AD kernels, as the Jacobian contributions are extracted directly from the `ADReal` residual. The `ADFunctorInterface` provides the necessary mechanisms for this . - -### 8. Object execution ordering within a thread: materials before kernels? Dependency resolution? - -Within a single thread, the execution order of objects is crucial for correct dependency resolution. -1. **Materials**: Material properties are typically computed first for an element. The `ComputeMaterialsObjectThread` is responsible for reinitializing and computing material properties for the current element, boundary, or neighbor element . This ensures that material properties are available to kernels that depend on them. -2. **Kernels**: After materials are reinitialized, `Kernel` objects are executed. The `NonlinearThread::computeOnElement()` method iterates through the active kernels for the current element . -3. **Dependency Resolution**: MOOSE's input file parsing and object registration system builds a dependency graph. Objects declare their dependencies (e.g., a kernel depends on a material property or another variable). The framework uses this information to ensure that objects are executed in the correct order. For example, `FEProblemBase::reinitScalars()` is called to reinitialize scalar variables, which might be dependencies for other computations . - -The `MooseObjectTagWarehouse` is used to manage and retrieve objects based on tags, which can influence their execution order . The `determineObjectWarehouses()` method in `NonlinearThread` is responsible for determining which objects will be computed based on vector/matrix tag information . - -## Relationships - -` ` `mermaid -graph TD - A[Executioner] --> B(FEProblemSolve) - B --> C[FEProblem] - C --> D[NonlinearSystemBase] - D --> E[ThreadedElementLoop] - E --> F[NonlinearThread] - F --> G[Assembly] - G --> H[Kernel] - G --> I[ADKernel] - - subgraph Threading - E -- "Splits element ranges" --> J[libMesh::n_threads()] - J -- "Each thread has" --> G - end - - subgraph Element Loop - F -- "1. reinit(elem)" --> C - F -- "2. computeOnElement()" --> H - F -- "2. computeOnElement()" --> I - H -- "3. accumulate _local_re/_local_ke" --> G - -Wiki pages you might want to explore: -- [Executioner and Time Integration (idaholab/moose)](https://deepwiki.com/idaholab/moose#3.2) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-total-lagrangian.md b/packages/akms/src/akms/_bundled/global_nodes/moose-total-lagrangian.md deleted file mode 100644 index 6e438b2..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-total-lagrangian.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -id: moose-total-lagrangian -title: MOOSE Total Lagrangian formulation in MOOSE -domain: constitutive -subdomain: algorithmic -tags: -- total-lagrangian -- 2nd-piola-kirchhoff -- stress-divergence -- reference-configuration -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-objectivity-frame-operations - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-objectivity-frame-operations -- to: cm-kinematics-tl - type: implements - weight: 0.9 - note: Total Lagrangian formulation with PK2 stress ---- - -# MOOSE Total Lagrangian formulation in MOOSE - -MOOSE implements a total Lagrangian formulation in Tensor Mechanics through specific kernels and material properties, primarily using the `TotalLagrangianStressDivergence` kernel and related `ComputeLagrangianStrain` and `ComputeLagrangianStressBase` material classes . This approach uses the initial, undeformed configuration as the reference for stress divergence calculations . - -## MOOSE's Total Lagrangian Implementation - -### 1. Total Lagrangian Approach and Stress Divergence -MOOSE implements the total Lagrangian approach by formulating the equilibrium equations in the initial, undeformed configuration . The stress divergence is computed using the 1st Piola-Kirchhoff stress tensor (`_pk1`) and the gradient of the test function in the reference configuration . - -The weak form of the stress divergence in the reference configuration is given by: -$$ -\int_{V_0} \mathbf{P} : \nabla_0 \delta \mathbf{u} \, dV_0 = \int_{V_0} \mathbf{b}_0 \cdot \delta \mathbf{u} \, dV_0 + \int_{A_0} \mathbf{t}_0 \cdot \delta \mathbf{u} \, dA_0 -$$ -where $\mathbf{P}$ is the 1st Piola-Kirchhoff stress tensor, $\nabla_0$ is the gradient with respect to the reference configuration, $\delta \mathbf{u}$ is the virtual displacement, $\mathbf{b}_0$ is the body force per unit reference volume, and $\mathbf{t}_0$ is the traction per unit reference area . - -The `TotalLagrangianStressDivergenceBase::computeQpResidual()` method calculates the residual contribution for the weak form as: -$$ -\text{gradTest}(\alpha) : \text{_pk1}[\text{_qp}] -$$ -where `gradTest` is the gradient of the test function and `_pk1` is the 1st Piola-Kirchhoff stress . - -### 2. `StressDivergenceTensors` with `use_displaced_mesh = false` -The `StressDivergenceTensors` kernel is part of the older kernel system . While it has a `use_displaced_mesh` parameter, setting it to `false` does not make it a total Lagrangian formulation in the context of the *new* Lagrangian kernel system . The new Lagrangian kernel system explicitly uses `TotalLagrangianStressDivergence` for the total Lagrangian path . The `TotalLagrangianStressDivergenceBase` explicitly suppresses the `use_displaced_mesh` parameter, enforcing that it is off . - -### 3. Deformation Gradient Computation and Storage -The deformation gradient `F` is computed by the `ComputeLagrangianStrain` class . For large deformations, it is calculated as $F_{iJ} = \delta_{iJ} + \frac{\partial u_i}{\partial X_J}$ . This `F` is then stored as a `MaterialProperty` and is accessible to other material models and kernels through its name, typically `deformation_gradient` . For example, `ComputeLagrangianStressCauchy` and `ComputeLagrangianStressPK1` retrieve it using `getMaterialPropertyByName(_base_name + "deformation_gradient")` . - -### 4. 2nd Piola-Kirchhoff Stress (S) vs Cauchy Stress (σ) -MOOSE's new Lagrangian material system, represented by `ComputeLagrangianStressBase`, is designed to provide both Cauchy stress (`_cauchy_stress`) and 1st Piola-Kirchhoff stress (`_pk1_stress`) . The 2nd Piola-Kirchhoff stress (`_S`) is typically computed by specialized material models like `ComputeLagrangianStressPK2` or `ComputeNeoHookeanStress` . - -The conversion from 2nd Piola-Kirchhoff stress (S) to 1st Piola-Kirchhoff stress (P) and then to Cauchy stress (σ) is handled within the `ComputeLagrangianStressPK2`, `ComputeLagrangianStressPK1`, and `ComputeLagrangianStressCauchy` classes . - -The conversion from 2nd Piola-Kirchhoff stress (S) to 1st Piola-Kirchhoff stress (P) is: -$$ -\mathbf{P} = \mathbf{F} \cdot \mathbf{S} \quad (1) -$$ -This is implemented in `ComputeLagrangianStressPK2::computeQpPK1Stress()` . - -The conversion from 1st Piola-Kirchhoff stress (P) to Cauchy stress (σ) is: -$$ -\sigma = \frac{1}{J} \mathbf{P} \cdot \mathbf{F}^T \quad (2) -$$ -This is implemented in `ComputeLagrangianStressPK1::computeQpCauchyStress()` . -Conversely, the conversion from Cauchy stress (σ) to 1st Piola-Kirchhoff stress (P) is: -$$ -\mathbf{P} = J \sigma \cdot \mathbf{F}^{-T} \quad (3) -$$ -This is implemented in `ComputeLagrangianStressCauchy::computeQpPK1Stress()` . - -### 5. Updated Lagrangian Option -MOOSE supports an updated Lagrangian formulation with `use_displaced_mesh = true` for large deformation kinematics . This is handled by the `UpdatedLagrangianStressDivergence` kernel . In this formulation, the equilibrium equations are written with respect to the current (deformed) configuration . The kernel requires the Cauchy stress (`_stress`) and its derivative with respect to the spatial velocity gradient (`_material_jacobian`) . - -### 6. Total Lagrangian vs. Updated Lagrangian Trade-offs -The choice between total Lagrangian and updated Lagrangian formulations in MOOSE is primarily managed by the `formulation` parameter within the `Physics/SolidMechanics/QuasiStatic` action, which can be set to `TOTAL` or `UPDATED` . - -* **Total Lagrangian:** - * Uses the initial configuration as the reference . - * Requires the 1st Piola-Kirchhoff stress and its derivative with respect to the deformation gradient . - * The `TotalLagrangianStressDivergence` kernel explicitly sets `use_displaced_mesh = false` . - * Homogenization constraints currently only support the total Lagrangian formulation . - -* **Updated Lagrangian:** - * Uses the current (deformed) configuration as the reference . - * Requires the Cauchy stress and its derivative with respect to the spatial velocity gradient . - * The `UpdatedLagrangianStressDivergence` kernel requires `use_displaced_mesh = true` for large kinematics . - -The trade-offs involve whether the reference configuration needs to be recomputed at each step (updated Lagrangian) or remains constant (total Lagrangian). The total Lagrangian formulation simplifies some aspects by always referring to the initial geometry, while the updated Lagrangian formulation is often more natural for rate-dependent material models. - -### 7. `ComputeLagrangianStrain` vs. `ComputeFiniteStrain` -* **`ComputeLagrangianStrain`**: This class is part of the new Lagrangian kernel system . It calculates kinematic quantities for both small and large deformation theories, controlled by the `large_kinematics` flag . It computes the deformation gradient `F` and various strain measures, including incremental and total strains . It also includes stabilization options like $\bar{F}$ stabilization . It explicitly requires `use_displaced_mesh=false` . - -* **`ComputeFiniteStrain`**: This class belongs to the older kernel system . It calculates finite strain measures but is not directly integrated with the new Lagrangian kernel system's material and kernel interfaces . The new Lagrangian kernel system aims to provide exact large deformation Jacobians without requiring AD, which is a key difference . - -The formulation choice propagates through the code via the `_lagrangian_kernels` and `_lk_formulation` flags within the `QuasiStaticSolidMechanicsPhysics` action . These flags determine which stress divergence kernel (`TotalLagrangianStressDivergence` or `UpdatedLagrangianStressDivergence`) and which strain calculator (`ComputeLagrangianStrain`) are instantiated . - -## Classes & Methods - -* `TotalLagrangianStressDivergenceBase::computeQpResidual()`: Calculates the residual contribution for the total Lagrangian weak form - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-viscoplastic-flow-rules.md b/packages/akms/src/akms/_bundled/global_nodes/moose-viscoplastic-flow-rules.md deleted file mode 100644 index 3ccb134..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-viscoplastic-flow-rules.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: moose-viscoplastic-flow-rules -title: MOOSE Viscoplastic flow rules and rate-dependent plasticity -domain: constitutive -subdomain: algorithmic -tags: -- viscoplasticity -- perzyna -- norton -- overstress -- rate-dependent -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-creep-viscoplasticity - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-creep-viscoplasticity -- to: cm-viscoplastic-thermo - type: implements - weight: 0.8 - note: Perzyna/Norton viscoplastic flow rules ---- - -# MOOSE Viscoplastic flow rules and rate-dependent plasticity - -MOOSE implements rate-dependent (viscoplastic) flow rules through several material classes, primarily `ADViscoplasticityStressUpdate` and `HyperbolicViscoplasticityStressUpdate` , which are designed to work within the `ComputeMultipleInelasticStress` framework . These classes handle the iterative solution for inelastic strain increments. - -## ADViscoplasticityStressUpdate and its Formulation - -The `ADViscoplasticityStressUpdate` class is a material model that calculates stress updates for viscoplastic materials using automatic differentiation. It inherits from `ADViscoplasticityStressUpdateBase` and `ADSingleVariableReturnMappingSolution` . The core of its formulation involves solving for the inelastic strain increment through a return mapping algorithm. - -### Perzyna-type and Norton-type Flow Rules - -`ADViscoplasticityStressUpdate` supports different viscoplastic models, specified by the `_model` enum . Currently, it explicitly lists `LPS` (presumably a form of power-law creep) and `GTN` (Gurson-Tvergaard-Needleman) models . The `_power` parameter and `_coefficient` are used to define the power-law relationship. - -A Norton-type power-law creep is exemplified in the `lps_dual.i` test case , where the `power` parameter is set to `3` and `1` respectively for two different models. The `coefficient` can be a constant or a material property, as shown in the example where `coef_3` is a temperature-dependent expression . - -For Perzyna-type viscoplasticity, the `NEML2` framework provides `PerzynaPlasticFlowRate` . This class takes `reference_stress` and `exponent` as parameters . - -### Overstress Functions: Yield Function Integration - -The `ADViscoplasticityStressUpdate` class calculates a residual in `computeResidual` which is driven to zero during the return mapping iterations. This residual implicitly incorporates the overstress concept, where viscoplastic flow occurs when the stress state exceeds a yield-like surface. The `effective_trial_stress` is a key input to this residual calculation . - -In the `NEML2` framework, the yield function is explicitly defined by classes like `YieldFunction` . The `flow` model can then be composed of `overstress`, `vonmises`, and `yield` models . The `Normality` class then uses this `flow` model to define the plastic flow direction. - -For `HyperbolicViscoplasticityStressUpdate` , the constitutive equation for scalar plastic strain rate is given by: -$$\dot{p} = \phi (\sigma_e , r) = \alpha \sinh \beta (\sigma_e -r - \sigma_y)$$ -Here, $\sigma_e$ is the effective stress, $r$ is a hardening variable, and $\sigma_y$ is the yield stress. The parameters `_c_alpha` and `_c_beta` correspond to $\alpha$ and $\beta$ respectively. The `computeResidual` method in this class is responsible for solving this equation. - -## Interaction with ComputeMultipleInelasticStress Framework - -The `ComputeMultipleInelasticStress` class is designed to combine multiple inelastic stress calculations, such as creep and plasticity . It iterates over individual inelastic models, which are typically derived from `StressUpdateBase` , until the change in stress converges . - -The `ADViscoplasticityStressUpdate` and `HyperbolicViscoplasticityStressUpdate` classes are examples of such inelastic models. They are configured as sub-materials within `ComputeMultipleInelasticStress` . The `updateQpState` method in `ComputeMultipleInelasticStress` orchestrates the iterative solution, calling the `updateState` method of each inelastic model . - -## Classes & Methods - -* `ADViscoplasticityStressUpdate::updateState()` : Updates the stress and inelastic strain increment for viscoplastic materials. -* `ADViscoplasticityStressUpdate::computeResidual()` : Computes the residual for the return mapping iteration. -* `HyperbolicViscoplasticityStressUpdate::computeResidual()` : Computes the residual for the hyperbolic sine viscoplasticity model. -* `ComputeMultipleInelasticStress::updateQpState()` : Manages the iterative update of stress and inelastic strains for multiple inelastic models. -* `HEVPFlowRatePowerLawJ2::computeValue()` : Calculates the flow rate based on a power-law relationship for hyperelastic viscoplasticity. - -## Equations - -### Hyperbolic Viscoplasticity Strain Rate -The constitutive equation for scalar plastic strain rate in `HyperbolicViscoplasticityStressUpdate` is: -$$ \dot{p} = \alpha \sinh \beta (\sigma_e -r - \sigma_y) $$ -where: -* $\dot{p}$ is the scalar plastic strain rate. -* $\alpha$ is the viscoplasticity coefficient (`_c_alpha`). -* $\beta$ is the viscoplasticity coefficient inside the hyperbolic sine function (`_c_beta`). -* $\sigma_e$ is the effective stress. -* $r$ is the hardening variable. -* $\sigma_y$ is the yield stress (`_yield_stress`). - -### Power Law Flow Rate (HEVP) -The flow rate in `HEVPFlowRatePowerLawJ2` is calculated as: -$$ \text{val} = \left(\frac{\text{eqv\_stress}}{\text{_strength[qp]}}\right)^{\text{_flow\_rate\_exponent}} \times \text{_ref\_flow\_rate} $$ -where: -* `eqv_stress` is the equivalent stress. -* `_strength[qp]` is the material strength at the quadrature point. -* `_flow_rate_exponent` is the power law exponent. -* `_ref_flow_rate` is the reference flow rate. - -## Parameters - -* `ADViscoplasticityStressUpdate` : - * `coefficient`: `ADMaterialProperty` (e.g., `coef_3 = '0.5e-18 * exp(-4e4 / 1.987 / temp)'`) - * `power`: `Real` (e.g., `3`, `1`) - * `base_name`: `String` (e.g., `'lps_1'`) -* `HyperbolicViscoplasticityStressUpdate` : - * `yield_stress`: `Real` (required) - * `hardening_constant`: `Real` (required) - * `c_alpha`: `Real` (required, viscoplasticity coefficient) - * `c_beta`: `Real` (required, viscoplasticity coefficient) -* `PerzynaPlasticFlowRate` (NEML2) : - * `reference_stress`: `Real` (e.g., `100`) - * `exponent`: `Real` (e.g., `2`) -* `HEVPFlowRatePowerLawJ2` : - * `reference_flow_rate`: `Real` (default `0.001`) - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-calphad.md b/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-calphad.md deleted file mode 100644 index 8344919..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-calphad.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -id: moose-wbm-calphad -title: MOOSE WBM thermodynamic coupling and CALPHAD integration -domain: phase-field -subdomain: algorithmic -tags: -- CALPHAD -- TDB -- parabolic-approximation -- Redlich-Kister -- temperature-dependence -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-wbm-kks-model - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-wbm-kks-model ---- - -# MOOSE WBM thermodynamic coupling and CALPHAD integration - -The WBM/KKS models in MOOSE connect to thermodynamic databases primarily through the `python/calphad/free_energy.py` script, which extracts free energy expressions from CALPHAD `.tdb` files and formats them for use with MOOSE's `DerivativeParsedMaterial` . This allows per-phase free energies to be directly incorporated into phase-field simulations. Temperature dependence and multi-component extensions like Redlich-Kister and sublattice models are handled by the CALPHAD data itself and then parsed into MOOSE's symbolic expression system . - -## Connecting CALPHAD Data to MOOSE - -### 1. Per-phase free energies from CALPHAD data and TDB file interface - -MOOSE can utilize per-phase free energies derived from CALPHAD data . The primary interface for this is the `python/calphad/free_energy.py` script . This script uses the `pycalphad` Python module to parse `.tdb` thermodynamic database files . It then exports these free energy expressions as MOOSE `Material` blocks, specifically using the `DerivativeParsedMaterial` class . - -**Algorithm Steps:** -` ` `pseudocode -1. User runs `free_energy.py` with a .tdb file and optional phase list. -2. `free_energy.py` opens the .tdb file using `pycalphad.Database`. -3. For each specified phase, a thermodynamic model is created using `pycalphad.Model`. -4. The free energy expression from the model is exported as a string using `fparser`. -5. MOOSE input file blocks are generated, defining a `DerivativeParsedMaterial` for each phase with the extracted function and its arguments. -` ` ` - - -**MOOSE Input Syntax:** -The `free_energy.py` script generates output similar to this for each phase: -` ` `ini - [./F_phase_name] - type = DerivativeParsedMaterial - function = 'CALPHAD_free_energy_expression' - args = 'variable1 variable2 ...' - [../] -` ` ` - - -### 2. Parabolic approximation of CALPHAD data - -The MOOSE documentation indicates that the `free_energy.py` tool directly exports CALPHAD functional expressions . This implies that MOOSE uses the full CALPHAD expressions rather than relying on parabolic approximations. The `DerivativeParsedMaterial` is designed to handle these complex functional forms and their derivatives symbolically . - -### 3. `TabulatedFluidProperties` for tabulated thermodynamic data - -While `TabulatedFluidProperties` exists in MOOSE for fluid simulations , it is part of the `fluid_properties` module and is designed for single-phase fluid properties based on pressure and temperature tables . It is not directly applicable to phase-field models for solid-state transformations where free energies are typically functions of order parameters and concentrations, and often derived from CALPHAD. The phase-field module uses `DerivativeParsedMaterial` for free energy expressions . - -### 4. Temperature dependence in per-phase free energies - -Temperature dependence is inherently included in the CALPHAD free energy expressions extracted by `free_energy.py` . When these expressions are parsed into `DerivativeParsedMaterial`, temperature can be included as one of the `args` (arguments) to the function . - -### 5. Multi-component extensions (Redlich-Kister, sublattice models) - -CALPHAD databases often incorporate multi-component extensions like Redlich-Kister and sublattice models . Since the `free_energy.py` script uses `pycalphad` to interpret the `.tdb` files , these complex models are handled by `pycalphad` during the extraction process. The resulting free energy expressions, which can be quite complex, are then passed to `DerivativeParsedMaterial` . `DerivativeParsedMaterial` is capable of handling arbitrary symbolic functions and their derivatives, making it suitable for these extensions . - -### 6. Higher-order derivatives from CALPHAD and numerical stability - -The `DerivativeParsedMaterial` class in MOOSE is designed to automatically compute derivatives of the free energy expressions . This symbolic differentiation capability helps in maintaining numerical stability by providing exact derivatives, rather than relying on numerical approximations that can introduce errors. The `KKSPhaseConcentrationMultiPhaseMaterial` uses nested Newton iterations to solve for phase concentrations, which requires derivatives of the free energies . The accuracy of these derivatives is crucial for the stability and convergence of the solver. - -## Practical Approaches for Connecting Phase Field with Thermodynamic Data - -### Classes & Methods: -* `python/calphad/free_energy.py`: A Python script that extracts free energy expressions from `.tdb` files and generates MOOSE input blocks . -* `DerivativeParsedMaterial`: A MOOSE material class that takes a symbolic function string and its arguments, and automatically computes its derivatives . -* `KKSMultiFreeEnergy::validParams()`: Defines the input parameters for the `KKSMultiFreeEnergy` AuxKernel, including lists of free energy functions, switching functions, and barrier functions for each phase . -* `KKSPhaseConcentrationMultiPhaseMaterial::validParams()`: Defines input parameters for the `KKSPhaseConcentrationMultiPhaseMaterial`, which computes KKS phase concentrations using a nested Newton iteration . It requires free energy material objects (`Fj_names`) and their derivatives . - -### Relationships: -` ` `mermaid -classDiagram - direction LR - class "python/calphad/free_energy.py" as FreeEnergyScript - class "pycalphad" as Pycalphad - class "Database" as TDBDatabase - class "Model" as PycalphadModel - class "DerivativeParsedMaterial" as DerivativeParsedMaterial - class "KKSMultiFreeEnergy" as KKSMultiFreeEnergy - class "KKSPhaseConcentrationMultiPhaseMaterial" as KKSPhaseConcentrationMultiPhaseMaterial - class "TotalFreeEnergyBase" as TotalFreeEnergyBase - class "Material" as Material - - FreeEnergyScript --> Pycalphad : uses - Pycalphad --> TDBDatabase : parses - Pycalphad --> PycalphadModel : creates - FreeEnergyScript --> DerivativeParsedMaterial : generates_input_for - DerivativeParsedMaterial --|> Material : inherits - KKSMultiFreeEnergy --|> TotalFreeEnergyBase : inherits - KKSPhaseConcentrationMultiPhaseMaterial --|> Material : inherits - KKSMultiFreeEnergy ..> DerivativeParsedMaterial : uses_Fj_names - KKSPhaseConcentrationMultiPhaseMaterial ..> DerivativeParsedMaterial : uses_Fj_names -` ` ` - - -## Notes -The `CALPHAD.md` documentation explicitly states that the `free_energy.py` script is a "work in progress" . This suggests that while the functionality exists, it may still be under active development or refinement. The `PFParamsPolyFreeEnergy` material is mentioned as calculating properties for a single-component phase field model using polynomial free energies, which is a simpler approach compared to direct CALPHAD coupling and might be used for quantitative models as indicated in `modules/phase_field/doc/content/modules/phase_field/index.md` . - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-formulation.md b/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-formulation.md deleted file mode 100644 index c7ab3df..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-formulation.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: moose-wbm-formulation -title: MOOSE WBM multi-phase field model formulation -domain: phase-field -subdomain: algorithmic -tags: -- WBM -- KKS -- per-phase-composition -- equal-chemical-potential -- lagrange-multiplier -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-wbm-kks-model - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-wbm-kks-model ---- - -# MOOSE WBM multi-phase field model formulation - -The Wheeler-Boettinger-McFadden (WBM) multi-phase field model in MOOSE is a framework for simulating phase transformations with multiple phases and compositions. It distinguishes itself by allowing each phase to have its own composition field, unlike models with a single global composition. MOOSE implements this through specific material and kernel classes that handle the free energy functional, enforce chemical potential equality, and manage phase and composition evolution. - -## 1. The WBM Free Energy Functional - -The total free energy in the WBM model, as implemented in MOOSE, is expressed as a sum over the individual phase free energies, weighted by switching functions, and includes gradient energy terms. For a multi-phase KKS system, the total free energy $F$ is given by: -$$ -F = \sum_i h_i F_i + W \sum_i g_i + \sum_i \frac{\kappa_i}{2} |\nabla \eta_i|^2 \quad (1) -$$ -Here, $h_i$ are switching functions, $F_i$ are the free energies of each phase $i$, $W$ is a double-well height parameter, $g_i$ are barrier functions, and $\kappa_i$ are gradient energy coefficients associated with the phase field variables $\eta_i$. -The `KKSMultiFreeEnergy` AuxKernel calculates this total free energy. - -## 2. Key Distinction: Per-Phase Composition Fields - -In the WBM model, each phase $i$ has its own composition field $c_i^k$ for component $k$. This is a key distinction from models that use a single global composition. MOOSE handles this by using a nested Newton iteration to solve for these per-phase concentrations. The `KKSPhaseConcentrationMultiPhaseMaterial` class is responsible for computing these phase concentrations. - -## 3. Equal Chemical Potential Constraint - -The constraint of equal chemical potential $\mu_i^k = \mu_j^k$ across phases for each component is enforced through a kernel. For a two-phase system, this is expressed as $dF_a/dc_a = dF_b/dc_b$. The `KKSPhaseChemicalPotential` kernel enforces this equality. This kernel takes the free energy functions for two phases (`fa_name` and `fb_name`) and their corresponding concentrations (`variable` for $c_a$ and `cb` for $c_b$) as parameters. - -## 4. Phase Evolution Equation - -The phase evolution equation for $\phi_i$ (or $\eta_i$ in MOOSE's implementation) is generally given by: -$$ -\frac{\partial \phi_i}{\partial t} = -L \left( \frac{\partial f}{\partial \phi_i} - \kappa \nabla^2 \phi_i + \lambda \right) \quad (2) -$$ -where $\lambda$ is a Lagrange multiplier to enforce the constraint $\sum \phi_i = 1$. MOOSE uses a Lagrange multiplier based constraint for keeping the sum of all phase order parameters equal to one. This is demonstrated in input files like `lagrange_multiplier.i` where `eta1 + eta2 = 1` is enforced. - -## 5. Diffusion Equations - -The evolution of each phase's composition and interdiffusion is handled by ensuring concentration conservation. The `KKSMultiPhaseConcentration` kernel enforces the concentration conservation equation $c = \sum_j h_j c_j$, where $c$ is the physical concentration and $c_j$ are the phase concentrations. This kernel takes an array of phase concentrations (`cj`), the physical concentration (`c`), and switching functions (`hj_names`) as input. - -## 6. Implementation Classes - -The primary MOOSE classes implementing the WBM model, particularly for multi-phase KKS, include: - -* `KKSPhaseChemicalPotential`: A kernel that enforces the equality of chemical potentials between phases. -* `KKSMultiPhaseConcentration`: A kernel that enforces the concentration conservation equation for multiple phases. -* `KKSPhaseConcentrationMultiPhaseMaterial`: A material class that computes the KKS phase concentrations using a nested Newton iteration to solve the equal chemical potential and concentration conservation equations for multiphase systems. -* `KKSMultiFreeEnergy`: An AuxKernel that computes the total free energy in a multi-phase KKS system, including chemical, barrier, and gradient terms. - -## 7. WBM vs. KKS in MOOSE - -In MOOSE, the WBM and KKS models are closely related and often discussed within the same framework, particularly for multi-phase systems. The KKS model is a specific type of phase-field model for binary alloys. The `KKSPhaseChemicalPotential` and `KKSMultiPhaseConcentration` classes are explicitly named with "KKS", indicating their role in implementing the KKS framework. The documentation refers to "KKS" as a model with "per-phase concentrations, two phases" or "per-phase concentrations, per-sublattice concentrations, multiple phases" . The WBM model is described as handling "$N$ phases, $N$ phase order parameters" . Essentially, the KKS model, as implemented in MOOSE, leverages the WBM framework's ability to handle per-phase compositions and multiple order parameters to describe multi-component, multi-phase systems. The `KKSMultiFreeEnergy` AuxKernel, for instance, computes the total free energy in a "multi-phase KKS system". - -## Classes & Methods - -* `KKSPhaseChemicalPotential::validParams()`: Defines the valid input parameters for the `KKSPhaseChemicalPotential` kernel. -* `KKSPhaseChemicalPotential::KKSPhaseChemicalPotential()`: Constructor for the `KKSPhaseChemicalPotential` kernel, initializing member variables. -* `KKSMultiPhaseConcentration::validParams()`: Defines the valid input parameters for the `KKSMultiPhaseConcentration` kernel. -* `KKSMultiPhaseConcentration::KKSMultiPhaseConcentration()`: Constructor for the `KKSMultiPhaseConcentration` kernel. -* `KKSPhaseConcentrationMultiPhaseMaterial::validParams()`: Defines the valid input parameters for the `KKSPhaseConcentrationMultiPhaseMaterial`. -* `KKSPhaseConcentrationMultiPhaseMaterial::KKSPhaseConcentrationMultiPhaseMaterial()`: Constructor for the `KKSPhaseConcentrationMultiPhaseMaterial`. -* `KKSMultiFreeEnergy::validParams()`: Defines the valid input parameters for the `KKSMultiFreeEnergy` AuxKernel. -* `KKSMultiFreeEnergy::KKSMultiFreeEnergy()`: Constructor for the `KKSMultiFreeEnergy` AuxKernel. - -## Equations - -### Total Free Energy Functional -$$ -F = \sum_i h_i F_i + W \sum_i g_i + \sum_i \frac{\kappa_i}{2} |\nabla \eta_i|^2 \quad (1) -$$ - -### Equal Chemical Potential Constraint -$$ -\frac{dF_a}{dc_a} = \frac{dF_b}{dc_b} \quad (2) -$$ - -### Phase Evolution Equation -$$ -\frac{\partial \phi_i}{\partial t} = -L \left( \frac{\partial f}{\partial \phi_i} - \kappa \nabla^2 \phi_i + \lambda \right) \quad (3) -$$ - -### Concentration Conservation -$$ -c = \sum_j h_j c_j \quad (4) -$$ - -## Parameters - -* `KKSPhaseChemicalPotential` parameters: - * `cb`: Coupled variable for phase b concentration. - * `fa_name`: Base name of the free energy function for phase a. - * `fb_name`: Base name of the free energy function for phase b. - * `ka`: Site fraction for the $c_a$ variable (default: 1.0). - * `kb`: Site fraction for the $c_b$ variable (default: 1.0). - * `args_a`: Vector of further parameters to $F_a$. - * `args_b`: Vector of further parameters to $F_b$. -* `KKSMultiPhaseConcentration` parameters: - * `cj`: Array of phase concentrations. - * `c`: Physical concentration. - * `etas`: Order parameters for all phases. - * `hj_names`: Switching Function Materials that provide $h(\eta_1, \eta_2, \dots)$. -* `KKSPhaseConcentrationMultiPhaseMaterial` parameters: - * `global_cs`: The interpolated concentrations. - * `all_etas`: Order parameters. - * `hj_names`: Switching functions in the same order as `all_etas`. - * `Fj_names`: Free energy material objects in the same order as `all_etas - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-implementation.md b/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-implementation.md deleted file mode 100644 index 580db29..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-implementation.md +++ /dev/null @@ -1,247 +0,0 @@ ---- -id: moose-wbm-implementation -title: MOOSE WBM implementation details and usage -domain: phase-field -subdomain: procedural -tags: -- KKSPhaseConcentration -- KKSPhaseChemicalPotential -- KKSSplitCHCRes -- KKSMulti -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: small -reading_priority: full -akms_schema: v2 -edges: -- to: moose-wbm-kks-model - type: refines - weight: 0.9 - note: Fine-grained aspect of moose-wbm-kks-model ---- - -# MOOSE WBM implementation details and usage - -This response outlines how to set up a WBM (or KKS-type) multi-phase field simulation in MOOSE, focusing on variable setup, relevant kernels, free energy specification, and practical considerations. It also provides an input file skeleton for a WBM problem. - -## Variable Setup -For a multi-phase, multi-component KKS simulation, you will need the following variables: -* **Order Parameters ($\eta_i$)**: One order parameter variable (`eta`) for each phase. For an N-phase system, you will have N order parameters. These are typically `FIRST` order, `LAGRANGE` family variables. -* **Global Concentration ($c$)**: One global concentration variable (`c`) for each component. This represents the overall concentration of a component in the system. These are also typically `FIRST` order, `LAGRANGE` family variables. -* **Phase Concentrations ($c_i$)**: One phase concentration variable (`ci`) for each component within each phase. These are not directly solved as nonlinear variables but are material properties computed by `KKSPhaseConcentrationMultiPhaseMaterial`. -* **Chemical Potential ($\mu$)**: A chemical potential variable (`mu` or `w`) is needed for the Cahn-Hilliard equation in a split formulation. - -For a 3-phase, 2-component problem, you would typically need: -* 3 order parameter variables ($\eta_1, \eta_2, \eta_3$). -* 2 global concentration variables ($c_A, c_B$). -* 2 chemical potential variables ($\mu_A, \mu_B$). -This results in a total of $3 + 2 + 2 = 7$ nonlinear variables. - -## Kernels for Phase and Composition Evolution - -### Phase Evolution (Allen-Cahn Equation) -The evolution of the order parameters ($\eta_i$) is governed by Allen-Cahn type equations. The relevant kernels are: -* `TimeDerivative`: For the time derivative term of the Allen-Cahn equation. -* `NestedKKSMultiACBulkF`: Handles the bulk free energy term for the Allen-Cahn equation. It takes into account the free energies of all phases and their derivatives with respect to the order parameters. -* `NestedKKSMultiACBulkC`: Accounts for the chemical potential contribution to the Allen-Cahn equation. -* `ACInterface`: Handles the interfacial energy term (gradient energy) for the Allen-Cahn equation. - -### Composition Evolution (Cahn-Hilliard Equation) -The evolution of the global concentration ($c$) is governed by the Cahn-Hilliard equation. In a split formulation, this involves: -* `CoupledTimeDerivative`: For the time derivative of the chemical potential. -* `NestedKKSMultiSplitCHCRes`: This kernel is used in the split Cahn-Hilliard formulation. It represents the bulk free energy contribution to the Cahn-Hilliard equation, specifically the term related to the derivative of the free energy with respect to the global concentration. -* `SplitCHWRes`: Handles the mobility and gradient terms related to the chemical potential in the split Cahn-Hilliard equation. - -## `KKSPhaseConcentration` and `KKSPhaseChemicalPotential` - -### `KKSMultiPhaseConcentration` -This kernel enforces the conservation of the global concentration, stating that the global concentration `c` is a weighted sum of the phase concentrations `c_j`, where the weights are the switching functions `h_j`. -The equation enforced is: -$$ c = \sum_j h_j(\eta_1, \dots, \eta_N) c_j $$ -The non-linear variable for this kernel is one of the phase concentrations ($c_n$), while other phase concentrations ($c_j \neq c_n$) and the global concentration ($c$) are supplied as coupled variables. - -### `KKSPhaseChemicalPotential` -This kernel enforces the equality of chemical potentials between two phases. For a two-phase system, this means $\frac{dF_a}{dc_a} = \frac{dF_b}{dc_b}$. The non-linear variable for this kernel is one of the phase concentrations ($c_a$), and the other phase concentration ($c_b$) is a coupled variable. - -## Specifying Per-Phase Free Energies -Per-phase free energies are typically specified using `DerivativeParsedMaterial` objects. Each phase will have its own `DerivativeParsedMaterial` that defines its free energy expression as a function of its phase concentration. These materials should have `compute = false` and `material_property_names` and `additional_derivative_symbols` set to the phase concentration variable. - -## `KKSSplitCHCRes` Kernel -The `KKSSplitCHCRes` kernel is part of the split Cahn-Hilliard formulation. It calculates the bulk free energy contribution to the Cahn-Hilliard equation, specifically the term $\frac{\partial F}{\partial c}$. It leverages the KKS identity $dF/dc = dF_a/dc_a (= dF_b/dc_b)$. The non-linear variable for this kernel is the global concentration `c`. - -## Multi-Phase Extension Kernels - -### `KKSMultiPhaseConcentration` -As described above, this kernel enforces the global concentration conservation equation $c = \sum_j h_j c_j$. - -### `NestedKKSMultiACBulkC` -This kernel contributes to the Allen-Cahn equation for an order parameter ($\eta_i$). It accounts for the chemical potential term in the multi-phase KKS model. - -### `NestedKKSMultiACBulkF` -This kernel also contributes to the Allen-Cahn equation for an order parameter ($\eta_i$). It handles the bulk free energy contribution, which includes the free energies of all phases and their derivatives with respect to the order parameters. - -## Input File Skeleton for a WBM Problem - -Here is a complete input file skeleton for a 3-phase, 1-component WBM problem, adapted from `kks_example_multiphase_nested.i` and `kks_example_multiphase_nested_damped.i` . - -` ` `ini -[Mesh] - type = GeneratedMesh - dim = 2 - nx = 20 - ny = 20 - xmin = 0 - xmax = 40 - ymin = 0 - ymax = 40 - elem_type = QUAD4 -[] - -[Variables] - # Global concentration - [c] - order = FIRST - family = LAGRANGE - [] - - # Order parameters for 3 phases - [eta1] - order = FIRST - family = LAGRANGE - initial_condition = 1.0 # Example initial condition - [] - [eta2] - order = FIRST - family = LAGRANGE - initial_condition = 0.0 - [] - [eta3] - order = FIRST - family = LAGRANGE - initial_condition = 0.0 - [] - - # Chemical potential for Cahn-Hilliard - [mu] - order = FIRST - family = LAGRANGE - [] -[] - -[AuxVariables] - [Energy] - order = CONSTANT - family = MONOMIAL - [] -[] - -[Materials] - # Per-phase free energies (F1, F2, F3) - [F1] - type = DerivativeParsedMaterial - property_name = F1 - expression = '20*(c1-0.2)^2' # Example free energy expression - material_property_names = 'c1' - additional_derivative_symbols = 'c1' - compute = false - [] - [F2] - type = DerivativeParsedMaterial - property_name = F2 - expression = '20*(c2-0.5)^2' - material_property_names = 'c2' - additional_derivative_symbols = 'c2' - compute = false - [] - [F3] - type = DerivativeParsedMaterial - property_name = F3 - expression = '20*(c3-0.8)^2' - material_property_names = 'c3' - additional_derivative_symbols = 'c3' - compute = false - [] - - # KKS Multi-Phase Concentration Material - # This material computes the phase concentrations (c1, c2, c3) - [KKSPhaseConcentrationMultiPhaseMaterial] - type = KKSPhaseConcentrationMultiPhaseMaterial - global_cs = 'c' # Global concentration variable - all_etas = 'eta1 eta2 eta3' # All order parameters - hj_names = 'h1 h2 h3' # Switching functions - ci_names = 'c1 c2 c3' # Phase concentrations (computed properties) - ci_IC = '0.2 0.5 0.8' # Initial guess for phase concentrations - Fj_names = 'F1 F2 F3' # Per-phase free energy materials - min_iterations = 1 - max_iterations = 1000 - absolute_tolerance = 1e-11 - relative_tolerance = 1e-10 - # damped_Newton = true # Uncomment for damped Newton solver - # conditions = C # Uncomment if using damped Newton with conditions - [] - - # KKS Multi-Phase Concentration Derivatives Material - # This material computes derivatives needed by kernels - [KKSPhaseConcentrationMultiPhaseDerivatives] - type = KKSPhaseConcentrationMultiPhaseDerivatives - global_cs = 'c' - all_etas = 'eta1 eta2 eta3' - Fj_names = 'F1 F2 F3' - hj_names = 'h1 h2 h3' - ci_names = 'c1 c2 c3' - [] - - # Switching functions for each phase (h1, h2, h3) - # These define how the phases mix - [h1] - type = SwitchingFunction3PhaseMaterial - eta_i = eta1 - eta_j = eta2 - eta_k = eta3 - property_name = h1 - [] - [h2] - type = SwitchingFunction3PhaseMaterial - eta_i = eta2 - eta_j = eta3 - eta_k = eta1 - property_name = h2 - [] - [h3] - type = SwitchingFunction3PhaseMaterial - eta_i = eta3 - eta_j = eta1 - eta_k = eta2 - property_name = h3 - [] - - # Barrier functions for each phase (g1, g2, g3) - # Used in Allen-Cahn bulk free energy - [g1] - type = BarrierFunctionMaterial - g_order = SIMPLE - eta = eta1 - function_name = g1 - [] - [g2] - type = BarrierFunctionMaterial - g_order = SIMPLE - eta = eta2 - function_name = g2 - [] - [g3] - type = BarrierFunctionMaterial - g_order = SIMPLE - eta = eta3 - function_name = g3 - [] - - # Constant properties (mobility, interfacial energy coefficient) - [constants] - type = GenericConstantMaterial - prop_names = 'L kappa M' - prop_values = '0.7 1.0 0.025' - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-kks-model.md b/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-kks-model.md deleted file mode 100644 index cb5c666..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/moose-wbm-kks-model.md +++ /dev/null @@ -1,458 +0,0 @@ ---- -id: moose-wbm-kks-model -title: MOOSE WBM — Wheeler-Boettinger-McFadden Multi-Phase Model -domain: phase-field -subdomain: algorithmic -tags: -- WBM -- KKS -- Kim-Kim-Suzuki -- equal-chemical-potential -- per-phase-composition -- CALPHAD -- multi-phase -- lagrange-multiplier -status: tentative -confidence: 0.8 -confidence_floor: 0.55 -source: agent -context_size: large -reading_priority: full -akms_schema: v2 -edges: -- to: moose-derivative-parsed-material - type: requires - weight: 0.6 - note: Uses DerivativeParsedMaterial for free energy definitions -- to: moose-multi-phase-component - type: requires - weight: 0.9 - note: WBM/KKS builds on multi-phase infrastructure -- to: moose-allen-cahn-cahn-hilliard - type: requires - weight: 0.7 - note: WBM uses Allen-Cahn for phase evolution -- to: cm-phase-field-fracture - type: implements - weight: 0.3 - note: WBM/KKS shares phase field variational framework ---- - -# MOOSE WBM — Wheeler-Boettinger-McFadden Multi-Phase Model - -Framework knowledge node covering 3 aspect(s) of WBM — Wheeler-Boettinger-McFadden Multi-Phase Model. - -## WBM multi-phase field model formulation - -The Wheeler-Boettinger-McFadden (WBM) multi-phase field model in MOOSE is a framework for simulating phase transformations with multiple phases and compositions. It distinguishes itself by allowing each phase to have its own composition field, unlike models with a single global composition. MOOSE implements this through specific material and kernel classes that handle the free energy functional, enforce chemical potential equality, and manage phase and composition evolution. - -## 1. The WBM Free Energy Functional - -The total free energy in the WBM model, as implemented in MOOSE, is expressed as a sum over the individual phase free energies, weighted by switching functions, and includes gradient energy terms. For a multi-phase KKS system, the total free energy $F$ is given by: -$$ -F = \sum_i h_i F_i + W \sum_i g_i + \sum_i \frac{\kappa_i}{2} |\nabla \eta_i|^2 \quad (1) -$$ -Here, $h_i$ are switching functions, $F_i$ are the free energies of each phase $i$, $W$ is a double-well height parameter, $g_i$ are barrier functions, and $\kappa_i$ are gradient energy coefficients associated with the phase field variables $\eta_i$. -The `KKSMultiFreeEnergy` AuxKernel calculates this total free energy. - -## 2. Key Distinction: Per-Phase Composition Fields - -In the WBM model, each phase $i$ has its own composition field $c_i^k$ for component $k$. This is a key distinction from models that use a single global composition. MOOSE handles this by using a nested Newton iteration to solve for these per-phase concentrations. The `KKSPhaseConcentrationMultiPhaseMaterial` class is responsible for computing these phase concentrations. - -## 3. Equal Chemical Potential Constraint - -The constraint of equal chemical potential $\mu_i^k = \mu_j^k$ across phases for each component is enforced through a kernel. For a two-phase system, this is expressed as $dF_a/dc_a = dF_b/dc_b$. The `KKSPhaseChemicalPotential` kernel enforces this equality. This kernel takes the free energy functions for two phases (`fa_name` and `fb_name`) and their corresponding concentrations (`variable` for $c_a$ and `cb` for $c_b$) as parameters. - -## 4. Phase Evolution Equation - -The phase evolution equation for $\phi_i$ (or $\eta_i$ in MOOSE's implementation) is generally given by: -$$ -\frac{\partial \phi_i}{\partial t} = -L \left( \frac{\partial f}{\partial \phi_i} - \kappa \nabla^2 \phi_i + \lambda \right) \quad (2) -$$ -where $\lambda$ is a Lagrange multiplier to enforce the constraint $\sum \phi_i = 1$. MOOSE uses a Lagrange multiplier based constraint for keeping the sum of all phase order parameters equal to one. This is demonstrated in input files like `lagrange_multiplier.i` where `eta1 + eta2 = 1` is enforced. - -## 5. Diffusion Equations - -The evolution of each phase's composition and interdiffusion is handled by ensuring concentration conservation. The `KKSMultiPhaseConcentration` kernel enforces the concentration conservation equation $c = \sum_j h_j c_j$, where $c$ is the physical concentration and $c_j$ are the phase concentrations. This kernel takes an array of phase concentrations (`cj`), the physical concentration (`c`), and switching functions (`hj_names`) as input. - -## 6. Implementation Classes - -The primary MOOSE classes implementing the WBM model, particularly for multi-phase KKS, include: - -* `KKSPhaseChemicalPotential`: A kernel that enforces the equality of chemical potentials between phases. -* `KKSMultiPhaseConcentration`: A kernel that enforces the concentration conservation equation for multiple phases. -* `KKSPhaseConcentrationMultiPhaseMaterial`: A material class that computes the KKS phase concentrations using a nested Newton iteration to solve the equal chemical potential and concentration conservation equations for multiphase systems. -* `KKSMultiFreeEnergy`: An AuxKernel that computes the total free energy in a multi-phase KKS system, including chemical, barrier, and gradient terms. - -## 7. WBM vs. KKS in MOOSE - -In MOOSE, the WBM and KKS models are closely related and often discussed within the same framework, particularly for multi-phase systems. The KKS model is a specific type of phase-field model for binary alloys. The `KKSPhaseChemicalPotential` and `KKSMultiPhaseConcentration` classes are explicitly named with "KKS", indicating their role in implementing the KKS framework. The documentation refers to "KKS" as a model with "per-phase concentrations, two phases" or "per-phase concentrations, per-sublattice concentrations, multiple phases" . The WBM model is described as handling "$N$ phases, $N$ phase order parameters" . Essentially, the KKS model, as implemented in MOOSE, leverages the WBM framework's ability to handle per-phase compositions and multiple order parameters to describe multi-component, multi-phase systems. The `KKSMultiFreeEnergy` AuxKernel, for instance, computes the total free energy in a "multi-phase KKS system". - -## Classes & Methods - -* `KKSPhaseChemicalPotential::validParams()`: Defines the valid input parameters for the `KKSPhaseChemicalPotential` kernel. -* `KKSPhaseChemicalPotential::KKSPhaseChemicalPotential()`: Constructor for the `KKSPhaseChemicalPotential` kernel, initializing member variables. -* `KKSMultiPhaseConcentration::validParams()`: Defines the valid input parameters for the `KKSMultiPhaseConcentration` kernel. -* `KKSMultiPhaseConcentration::KKSMultiPhaseConcentration()`: Constructor for the `KKSMultiPhaseConcentration` kernel. -* `KKSPhaseConcentrationMultiPhaseMaterial::validParams()`: Defines the valid input parameters for the `KKSPhaseConcentrationMultiPhaseMaterial`. -* `KKSPhaseConcentrationMultiPhaseMaterial::KKSPhaseConcentrationMultiPhaseMaterial()`: Constructor for the `KKSPhaseConcentrationMultiPhaseMaterial`. -* `KKSMultiFreeEnergy::validParams()`: Defines the valid input parameters for the `KKSMultiFreeEnergy` AuxKernel. -* `KKSMultiFreeEnergy::KKSMultiFreeEnergy()`: Constructor for the `KKSMultiFreeEnergy` AuxKernel. - -## Equations - -### Total Free Energy Functional -$$ -F = \sum_i h_i F_i + W \sum_i g_i + \sum_i \frac{\kappa_i}{2} |\nabla \eta_i|^2 \quad (1) -$$ - -### Equal Chemical Potential Constraint -$$ -\frac{dF_a}{dc_a} = \frac{dF_b}{dc_b} \quad (2) -$$ - -### Phase Evolution Equation -$$ -\frac{\partial \phi_i}{\partial t} = -L \left( \frac{\partial f}{\partial \phi_i} - \kappa \nabla^2 \phi_i + \lambda \right) \quad (3) -$$ - -### Concentration Conservation -$$ -c = \sum_j h_j c_j \quad (4) -$$ - -## Parameters - -* `KKSPhaseChemicalPotential` parameters: - * `cb`: Coupled variable for phase b concentration. - * `fa_name`: Base name of the free energy function for phase a. - * `fb_name`: Base name of the free energy function for phase b. - * `ka`: Site fraction for the $c_a$ variable (default: 1.0). - * `kb`: Site fraction for the $c_b$ variable (default: 1.0). - * `args_a`: Vector of further parameters to $F_a$. - * `args_b`: Vector of further parameters to $F_b$. -* `KKSMultiPhaseConcentration` parameters: - * `cj`: Array of phase concentrations. - * `c`: Physical concentration. - * `etas`: Order parameters for all phases. - * `hj_names`: Switching Function Materials that provide $h(\eta_1, \eta_2, \dots)$. -* `KKSPhaseConcentrationMultiPhaseMaterial` parameters: - * `global_cs`: The interpolated concentrations. - * `all_etas`: Order parameters. - * `hj_names`: Switching functions in the same order as `all_etas`. - * `Fj_names`: Free energy material objects in the same order as `all_etas - - -## WBM implementation details and usage - -This response outlines how to set up a WBM (or KKS-type) multi-phase field simulation in MOOSE, focusing on variable setup, relevant kernels, free energy specification, and practical considerations. It also provides an input file skeleton for a WBM problem. - -## Variable Setup -For a multi-phase, multi-component KKS simulation, you will need the following variables: -* **Order Parameters ($\eta_i$)**: One order parameter variable (`eta`) for each phase. For an N-phase system, you will have N order parameters. These are typically `FIRST` order, `LAGRANGE` family variables. -* **Global Concentration ($c$)**: One global concentration variable (`c`) for each component. This represents the overall concentration of a component in the system. These are also typically `FIRST` order, `LAGRANGE` family variables. -* **Phase Concentrations ($c_i$)**: One phase concentration variable (`ci`) for each component within each phase. These are not directly solved as nonlinear variables but are material properties computed by `KKSPhaseConcentrationMultiPhaseMaterial`. -* **Chemical Potential ($\mu$)**: A chemical potential variable (`mu` or `w`) is needed for the Cahn-Hilliard equation in a split formulation. - -For a 3-phase, 2-component problem, you would typically need: -* 3 order parameter variables ($\eta_1, \eta_2, \eta_3$). -* 2 global concentration variables ($c_A, c_B$). -* 2 chemical potential variables ($\mu_A, \mu_B$). -This results in a total of $3 + 2 + 2 = 7$ nonlinear variables. - -## Kernels for Phase and Composition Evolution - -### Phase Evolution (Allen-Cahn Equation) -The evolution of the order parameters ($\eta_i$) is governed by Allen-Cahn type equations. The relevant kernels are: -* `TimeDerivative`: For the time derivative term of the Allen-Cahn equation. -* `NestedKKSMultiACBulkF`: Handles the bulk free energy term for the Allen-Cahn equation. It takes into account the free energies of all phases and their derivatives with respect to the order parameters. -* `NestedKKSMultiACBulkC`: Accounts for the chemical potential contribution to the Allen-Cahn equation. -* `ACInterface`: Handles the interfacial energy term (gradient energy) for the Allen-Cahn equation. - -### Composition Evolution (Cahn-Hilliard Equation) -The evolution of the global concentration ($c$) is governed by the Cahn-Hilliard equation. In a split formulation, this involves: -* `CoupledTimeDerivative`: For the time derivative of the chemical potential. -* `NestedKKSMultiSplitCHCRes`: This kernel is used in the split Cahn-Hilliard formulation. It represents the bulk free energy contribution to the Cahn-Hilliard equation, specifically the term related to the derivative of the free energy with respect to the global concentration. -* `SplitCHWRes`: Handles the mobility and gradient terms related to the chemical potential in the split Cahn-Hilliard equation. - -## `KKSPhaseConcentration` and `KKSPhaseChemicalPotential` - -### `KKSMultiPhaseConcentration` -This kernel enforces the conservation of the global concentration, stating that the global concentration `c` is a weighted sum of the phase concentrations `c_j`, where the weights are the switching functions `h_j`. -The equation enforced is: -$$ c = \sum_j h_j(\eta_1, \dots, \eta_N) c_j $$ -The non-linear variable for this kernel is one of the phase concentrations ($c_n$), while other phase concentrations ($c_j \neq c_n$) and the global concentration ($c$) are supplied as coupled variables. - -### `KKSPhaseChemicalPotential` -This kernel enforces the equality of chemical potentials between two phases. For a two-phase system, this means $\frac{dF_a}{dc_a} = \frac{dF_b}{dc_b}$. The non-linear variable for this kernel is one of the phase concentrations ($c_a$), and the other phase concentration ($c_b$) is a coupled variable. - -## Specifying Per-Phase Free Energies -Per-phase free energies are typically specified using `DerivativeParsedMaterial` objects. Each phase will have its own `DerivativeParsedMaterial` that defines its free energy expression as a function of its phase concentration. These materials should have `compute = false` and `material_property_names` and `additional_derivative_symbols` set to the phase concentration variable. - -## `KKSSplitCHCRes` Kernel -The `KKSSplitCHCRes` kernel is part of the split Cahn-Hilliard formulation. It calculates the bulk free energy contribution to the Cahn-Hilliard equation, specifically the term $\frac{\partial F}{\partial c}$. It leverages the KKS identity $dF/dc = dF_a/dc_a (= dF_b/dc_b)$. The non-linear variable for this kernel is the global concentration `c`. - -## Multi-Phase Extension Kernels - -### `KKSMultiPhaseConcentration` -As described above, this kernel enforces the global concentration conservation equation $c = \sum_j h_j c_j$. - -### `NestedKKSMultiACBulkC` -This kernel contributes to the Allen-Cahn equation for an order parameter ($\eta_i$). It accounts for the chemical potential term in the multi-phase KKS model. - -### `NestedKKSMultiACBulkF` -This kernel also contributes to the Allen-Cahn equation for an order parameter ($\eta_i$). It handles the bulk free energy contribution, which includes the free energies of all phases and their derivatives with respect to the order parameters. - -## Input File Skeleton for a WBM Problem - -Here is a complete input file skeleton for a 3-phase, 1-component WBM problem, adapted from `kks_example_multiphase_nested.i` and `kks_example_multiphase_nested_damped.i` . - -` ` `ini -[Mesh] - type = GeneratedMesh - dim = 2 - nx = 20 - ny = 20 - xmin = 0 - xmax = 40 - ymin = 0 - ymax = 40 - elem_type = QUAD4 -[] - -[Variables] - # Global concentration - [c] - order = FIRST - family = LAGRANGE - [] - - # Order parameters for 3 phases - [eta1] - order = FIRST - family = LAGRANGE - initial_condition = 1.0 # Example initial condition - [] - [eta2] - order = FIRST - family = LAGRANGE - initial_condition = 0.0 - [] - [eta3] - order = FIRST - family = LAGRANGE - initial_condition = 0.0 - [] - - # Chemical potential for Cahn-Hilliard - [mu] - order = FIRST - family = LAGRANGE - [] -[] - -[AuxVariables] - [Energy] - order = CONSTANT - family = MONOMIAL - [] -[] - -[Materials] - # Per-phase free energies (F1, F2, F3) - [F1] - type = DerivativeParsedMaterial - property_name = F1 - expression = '20*(c1-0.2)^2' # Example free energy expression - material_property_names = 'c1' - additional_derivative_symbols = 'c1' - compute = false - [] - [F2] - type = DerivativeParsedMaterial - property_name = F2 - expression = '20*(c2-0.5)^2' - material_property_names = 'c2' - additional_derivative_symbols = 'c2' - compute = false - [] - [F3] - type = DerivativeParsedMaterial - property_name = F3 - expression = '20*(c3-0.8)^2' - material_property_names = 'c3' - additional_derivative_symbols = 'c3' - compute = false - [] - - # KKS Multi-Phase Concentration Material - # This material computes the phase concentrations (c1, c2, c3) - [KKSPhaseConcentrationMultiPhaseMaterial] - type = KKSPhaseConcentrationMultiPhaseMaterial - global_cs = 'c' # Global concentration variable - all_etas = 'eta1 eta2 eta3' # All order parameters - hj_names = 'h1 h2 h3' # Switching functions - ci_names = 'c1 c2 c3' # Phase concentrations (computed properties) - ci_IC = '0.2 0.5 0.8' # Initial guess for phase concentrations - Fj_names = 'F1 F2 F3' # Per-phase free energy materials - min_iterations = 1 - max_iterations = 1000 - absolute_tolerance = 1e-11 - relative_tolerance = 1e-10 - # damped_Newton = true # Uncomment for damped Newton solver - # conditions = C # Uncomment if using damped Newton with conditions - [] - - # KKS Multi-Phase Concentration Derivatives Material - # This material computes derivatives needed by kernels - [KKSPhaseConcentrationMultiPhaseDerivatives] - type = KKSPhaseConcentrationMultiPhaseDerivatives - global_cs = 'c' - all_etas = 'eta1 eta2 eta3' - Fj_names = 'F1 F2 F3' - hj_names = 'h1 h2 h3' - ci_names = 'c1 c2 c3' - [] - - # Switching functions for each phase (h1, h2, h3) - # These define how the phases mix - [h1] - type = SwitchingFunction3PhaseMaterial - eta_i = eta1 - eta_j = eta2 - eta_k = eta3 - property_name = h1 - [] - [h2] - type = SwitchingFunction3PhaseMaterial - eta_i = eta2 - eta_j = eta3 - eta_k = eta1 - property_name = h2 - [] - [h3] - type = SwitchingFunction3PhaseMaterial - eta_i = eta3 - eta_j = eta1 - eta_k = eta2 - property_name = h3 - [] - - # Barrier functions for each phase (g1, g2, g3) - # Used in Allen-Cahn bulk free energy - [g1] - type = BarrierFunctionMaterial - g_order = SIMPLE - eta = eta1 - function_name = g1 - [] - [g2] - type = BarrierFunctionMaterial - g_order = SIMPLE - eta = eta2 - function_name = g2 - [] - [g3] - type = BarrierFunctionMaterial - g_order = SIMPLE - eta = eta3 - function_name = g3 - [] - - # Constant properties (mobility, interfacial energy coefficient) - [constants] - type = GenericConstantMaterial - prop_names = 'L kappa M' - prop_values = '0.7 1.0 0.025' - - - -## WBM thermodynamic coupling and CALPHAD integration - -The WBM/KKS models in MOOSE connect to thermodynamic databases primarily through the `python/calphad/free_energy.py` script, which extracts free energy expressions from CALPHAD `.tdb` files and formats them for use with MOOSE's `DerivativeParsedMaterial` . This allows per-phase free energies to be directly incorporated into phase-field simulations. Temperature dependence and multi-component extensions like Redlich-Kister and sublattice models are handled by the CALPHAD data itself and then parsed into MOOSE's symbolic expression system . - -## Connecting CALPHAD Data to MOOSE - -### 1. Per-phase free energies from CALPHAD data and TDB file interface - -MOOSE can utilize per-phase free energies derived from CALPHAD data . The primary interface for this is the `python/calphad/free_energy.py` script . This script uses the `pycalphad` Python module to parse `.tdb` thermodynamic database files . It then exports these free energy expressions as MOOSE `Material` blocks, specifically using the `DerivativeParsedMaterial` class . - -**Algorithm Steps:** -` ` `pseudocode -1. User runs `free_energy.py` with a .tdb file and optional phase list. -2. `free_energy.py` opens the .tdb file using `pycalphad.Database`. -3. For each specified phase, a thermodynamic model is created using `pycalphad.Model`. -4. The free energy expression from the model is exported as a string using `fparser`. -5. MOOSE input file blocks are generated, defining a `DerivativeParsedMaterial` for each phase with the extracted function and its arguments. -` ` ` - - -**MOOSE Input Syntax:** -The `free_energy.py` script generates output similar to this for each phase: -` ` `ini - [./F_phase_name] - type = DerivativeParsedMaterial - function = 'CALPHAD_free_energy_expression' - args = 'variable1 variable2 ...' - [../] -` ` ` - - -### 2. Parabolic approximation of CALPHAD data - -The MOOSE documentation indicates that the `free_energy.py` tool directly exports CALPHAD functional expressions . This implies that MOOSE uses the full CALPHAD expressions rather than relying on parabolic approximations. The `DerivativeParsedMaterial` is designed to handle these complex functional forms and their derivatives symbolically . - -### 3. `TabulatedFluidProperties` for tabulated thermodynamic data - -While `TabulatedFluidProperties` exists in MOOSE for fluid simulations , it is part of the `fluid_properties` module and is designed for single-phase fluid properties based on pressure and temperature tables . It is not directly applicable to phase-field models for solid-state transformations where free energies are typically functions of order parameters and concentrations, and often derived from CALPHAD. The phase-field module uses `DerivativeParsedMaterial` for free energy expressions . - -### 4. Temperature dependence in per-phase free energies - -Temperature dependence is inherently included in the CALPHAD free energy expressions extracted by `free_energy.py` . When these expressions are parsed into `DerivativeParsedMaterial`, temperature can be included as one of the `args` (arguments) to the function . - -### 5. Multi-component extensions (Redlich-Kister, sublattice models) - -CALPHAD databases often incorporate multi-component extensions like Redlich-Kister and sublattice models . Since the `free_energy.py` script uses `pycalphad` to interpret the `.tdb` files , these complex models are handled by `pycalphad` during the extraction process. The resulting free energy expressions, which can be quite complex, are then passed to `DerivativeParsedMaterial` . `DerivativeParsedMaterial` is capable of handling arbitrary symbolic functions and their derivatives, making it suitable for these extensions . - -### 6. Higher-order derivatives from CALPHAD and numerical stability - -The `DerivativeParsedMaterial` class in MOOSE is designed to automatically compute derivatives of the free energy expressions . This symbolic differentiation capability helps in maintaining numerical stability by providing exact derivatives, rather than relying on numerical approximations that can introduce errors. The `KKSPhaseConcentrationMultiPhaseMaterial` uses nested Newton iterations to solve for phase concentrations, which requires derivatives of the free energies . The accuracy of these derivatives is crucial for the stability and convergence of the solver. - -## Practical Approaches for Connecting Phase Field with Thermodynamic Data - -### Classes & Methods: -* `python/calphad/free_energy.py`: A Python script that extracts free energy expressions from `.tdb` files and generates MOOSE input blocks . -* `DerivativeParsedMaterial`: A MOOSE material class that takes a symbolic function string and its arguments, and automatically computes its derivatives . -* `KKSMultiFreeEnergy::validParams()`: Defines the input parameters for the `KKSMultiFreeEnergy` AuxKernel, including lists of free energy functions, switching functions, and barrier functions for each phase . -* `KKSPhaseConcentrationMultiPhaseMaterial::validParams()`: Defines input parameters for the `KKSPhaseConcentrationMultiPhaseMaterial`, which computes KKS phase concentrations using a nested Newton iteration . It requires free energy material objects (`Fj_names`) and their derivatives . - -### Relationships: -` ` `mermaid -classDiagram - direction LR - class "python/calphad/free_energy.py" as FreeEnergyScript - class "pycalphad" as Pycalphad - class "Database" as TDBDatabase - class "Model" as PycalphadModel - class "DerivativeParsedMaterial" as DerivativeParsedMaterial - class "KKSMultiFreeEnergy" as KKSMultiFreeEnergy - class "KKSPhaseConcentrationMultiPhaseMaterial" as KKSPhaseConcentrationMultiPhaseMaterial - class "TotalFreeEnergyBase" as TotalFreeEnergyBase - class "Material" as Material - - FreeEnergyScript --> Pycalphad : uses - Pycalphad --> TDBDatabase : parses - Pycalphad --> PycalphadModel : creates - FreeEnergyScript --> DerivativeParsedMaterial : generates_input_for - DerivativeParsedMaterial --|> Material : inherits - KKSMultiFreeEnergy --|> TotalFreeEnergyBase : inherits - KKSPhaseConcentrationMultiPhaseMaterial --|> Material : inherits - KKSMultiFreeEnergy ..> DerivativeParsedMaterial : uses_Fj_names - KKSPhaseConcentrationMultiPhaseMaterial ..> DerivativeParsedMaterial : uses_Fj_names -` ` ` - - -## Notes -The `CALPHAD.md` documentation explicitly states that the `free_energy.py` script is a "work in progress" . This suggests that while the functionality exists, it may still be under active development or refinement. The `PFParamsPolyFreeEnergy` material is mentioned as calculating properties for a single-component phase field model using polynomial free energies, which is a simpler approach compared to direct CALPHAD coupling and might be used for quantitative models as indicated in `modules/phase_field/doc/content/modules/phase_field/index.md` . - -Source: this node summarizes the MOOSE framework (https://github.com/idaholab/moose), indexed at https://deepwiki.com/idaholab/moose. See THIRD_PARTY_NOTICES.md for attribution and licensing. diff --git a/packages/akms/src/akms/_bundled/global_nodes/optim-as-solver.md b/packages/akms/src/akms/_bundled/global_nodes/optim-as-solver.md deleted file mode 100644 index 875d854..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/optim-as-solver.md +++ /dev/null @@ -1,277 +0,0 @@ ---- -id: optim-as-solver -title: Optimization-Based Nonlinear FEM Solvers -domain: computational-mechanics -subdomain: optimization -tags: -- optimization -- FEM-solver -- energy-minimization -- variational -- descent-guarantee -status: tentative -confidence: 0.85 -source: hybrid -confidence_floor: 0.7 -edges: -- to: optim-unconstrained-basics - type: requires - weight: 1.0 -- to: optim-lbfgs - type: feeds-into - weight: 0.5 -- to: optim-lbfgs-fem - type: feeds-into - weight: 0.5 -- to: pf-monolithic-bfgs - type: refines - weight: 0.7 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Optimization-Based Nonlinear FEM Solvers - -## Summary -Variational solid mechanics: equilibrium = minimum of total -potential energy Pi(u). Nonlinear FE solvers can target either -residual = 0 (Newton-style) or energy minimum (optimization-style). -Optimization approach gives guaranteed descent, robust handling -of softening / non-convex problems where Newton fails. L-BFGS, NCG, -trust-region all applicable. Limitation: requires conservative -constitutive law (path-independent psi); plasticity requires -incremental potential framework (Ortiz-Stainier 1999). - - -## 1. Core Concept -Two equivalent formulations of equilibrium: - -(1) Residual form (Newton): - F(u) = F_int(u) - F_ext = 0 -- Newton iterates: u_{k+1} = u_k - J^{-1} * F(u_k) -- Quadratic local convergence -- Globalization: line search, trust region -- Issue: J indefinite at peak load / softening; Newton fails - -(2) Energy form (optimization): - Pi(u) = psi_internal(u) - W_ext(u) (total potential energy) - min_u Pi(u) -- Optimization iterates: u_{k+1} = u_k + alpha_k * p_k -- L-BFGS, NCG, trust region -- Guaranteed monotone decrease in Pi (with line search) - -Equivalence: F = grad Pi; J = Hessian of Pi. - -Why optimization? -- Robust: descent direction always available (e.g., -grad Pi) -- No tangent assembly: gradient = residual already computed -- Quasi-Newton uses gradient differences: no Hessian -- Snap-back / softening: line search prevents divergence - -When applicable (conservative systems): -- Hyperelasticity (Ogden, Mooney-Rivlin, neo-Hookean) -- Brittle phase-field fracture (variational by construction) -- Variational plasticity (Ortiz-Stainier 1999, time-incremental - potential) -- Linear elasticity (psi quadratic) - -When NOT applicable: -- Path-dependent / dissipative (e.g., classical plasticity without - incremental potential) -- Rate-dependent viscoplasticity (J2-rate flow rule) -- Coulomb friction -- Damage with hysteresis - -Workaround: incremental energy (incremental potential): - Pi^inc(u_{n+1}) = psi(F^{n+1}) + dt * D(F^{n+1}, eps^p^{n+1}, ...) - - lambda * fy(sigma, eps^p) -Minimize this over (u, eps^p, lambda) at each time step -(Ortiz-Stainier). - -L-BFGS for FE (advantages): -- Memory: m * n vectors; n = DOFs (10^4-10^7) -- No Jacobian: just element-loop residual computation -- Super-linear convergence with strong Wolfe line search -- Production: standard for variational fracture (Wu 2020) - -Hybrid Newton/L-BFGS: -- Newton when J SPD (early iterations, far from peak) -- L-BFGS when J indefinite (snap-back, softening) -- Switch based on Newton convergence rate or eigenvalue check - -Practical recipes: -- Initial guess: u_0 from previous time step -- Line search: strong Wolfe, c1 = 1e-4, c2 = 0.9 -- Memory m = 10-20 typical -- Stopping: ||grad Pi||_max / ||F_ext|| < 1e-6 - -Caveats vs Newton: -- L-BFGS slower per iter but no tangent assembly -- Convergence super-linear vs Newton quadratic -- For smooth convex problems with cheap tangent, Newton wins -- For non-convex / complex tangent, L-BFGS wins - - -## 2. Mathematical Formulation -Variational equilibrium = stationarity of energy. Optimization -solvers leverage convexity / partial-convexity to ensure descent. - - -**total-potential-energy:** - -$$ -\Pi(\mathbf{u}) \;=\; \int_\Omega \psi(\mathbf{F}(\mathbf{u})) \, dV \;-\; \int_\Omega \mathbf{u} \cdot \mathbf{b} \, dV \;-\; \int_{\Gamma_t} \mathbf{u} \cdot \mathbf{t} \, dA -$$ - -where psi = strain energy density; b = body force; t = surface traction - -**variational-equilibrium:** - -$$ -\nabla \Pi(\mathbf{u}^*) \;=\; \mathbf{F}_{int}(\mathbf{u}^*) - \mathbf{F}_{ext} \;=\; \mathbf{0} -$$ - -where gradient of Pi = residual; equilibrium = stationarity - -**hessian-tangent-stiffness:** - -$$ -\nabla^2 \Pi(\mathbf{u}) \;=\; \mathbf{K}_T(\mathbf{u}) \;=\; \frac{\partial \mathbf{F}_{int}}{\partial \mathbf{u}} -$$ - -where Hessian of Pi = tangent stiffness; SPD for stable equilibrium - -**incremental-potential:** - -$$ -\Pi^{inc}(\mathbf{u}_{n+1}, \boldsymbol{\xi}_{n+1}) \;=\; \psi(\mathbf{F}_{n+1}, \boldsymbol{\xi}_{n+1}) - \boldsymbol{\xi}_{n+1}^T \mathbf{Y}_n + \Delta D(\boldsymbol{\xi}_{n+1}, \boldsymbol{\xi}_n) -$$ - -where Ortiz-Stainier 1999; xi = internal variables; Delta D = dissipation pseudo-potential; minimize over (u, xi) - -**descent-guarantee:** - -$$ -\Pi(\mathbf{u}_{k+1}) \;<\; \Pi(\mathbf{u}_k) \quad \forall k \;\;\text{(with Armijo line search)} -$$ - -where monotone decrease in energy; not guaranteed with Newton + indefinite J - -**convergence-comparison:** - -$$ -T_{Newton} \sim k_{Newton} \cdot T_{tangent-assembly + linear-solve} -$$ - -where Newton: few iter but expensive each; L-BFGS: more iter but cheap each - -**lbfgs-fem-cost:** - -$$ -T_{L-BFGS} \sim k_{L-BFGS} \cdot (T_{residual-assembly} + T_{line-search}) -$$ - -where no Jacobian assembly; gradient = residual already needed - -**Notation:** - -- $Pi(u)$ — total potential energy -- $psi(F)$ — strain energy density -- $F_int, F_ext$ — internal, external forces -- $K_T$ — tangent stiffness (Hessian of Pi) -- $xi$ — internal variables (plastic strain, hardening, ...) -- $D$ — dissipation pseudo-potential - - -## 3. Algorithmic Implementation -**Algorithm: lbfgs-as-fem-solver** - -$$ -\begin{algorithmic} -\State $$ -\State $$ -\State $$ -\State $$ -\State $$ -\State $$ -\State $$ -\State $$ -\State $$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -ti.kernel for F_int assembly (element loop). Pi evaluation -via element loop summing strain energies. L-BFGS state via -ti.field. - - -**Algorithm: hybrid-newton-lbfgs** - -$$ -\begin{algorithmic} -\State $$ -\State $$ -\State $$ -\State $$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Switch logic in Python; same kernels for Newton (Krylov + -tangent assembly) and L-BFGS (residual + line search). - - -**Algorithm: variational-plasticity-step** - -$$ -\begin{algorithmic} -\State $$ -\State $$ -\State $$ -\State $$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Two-phase loop: outer L-BFGS for u (cheap), inner return -mapping for eps_p (per-GP). Same data layout as standard FE. - - - -## 4. Known Pitfalls -**not-conservative-system:** Plasticity / damage with hysteresis: not derivable from a -potential. Energy minimization not applicable. Use Newton on -residual or incremental potential framework (Ortiz-Stainier). - - -**rate-dependent-flow:** Viscoplasticity with rate-dependent yield: standard variational -structure breaks. Incremental potential exists but more complex. - - -**line-search-too-loose:** Backtracking-only without curvature: L-BFGS loses super-linear -rate. Always use strong Wolfe. - - -**m-too-small-history:** m = 1-3: behaves like steepest descent + small memory. Default -m = 10 robust; larger m for tight problems. - - -**residual-vs-energy-stopping:** ||F||_inf < tol_F: standard FE convergence. Pi-based stopping -(|Pi_k - Pi_{k-1}| < tol_Pi) less robust for tight tolerances. - - -**ill-scaled-energy:** psi values vary wildly across mesh (e.g., concentrated stresses): -L-BFGS history dominated by hot-spot updates. Use diagonal -preconditioner H_0. - - -## 5. References -- Wu, J.-Y., Huang, Y., Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase-field damage theory. CMAME 360:112704. -- Ortiz, M., Stainier, L. (1999). The variational formulation of viscoplastic constitutive updates. CMAME 171:419-444. -- Mielke, A., Roubíček, T. (2015). Rate-Independent Systems: Theory and Application. Springer. -- Stainier, L., Ortiz, M. (2010). Study and validation of a variational theory of thermo-mechanical coupling in finite visco-plasticity. IJSS 47:705-715. -- Kelley, C. T. (1999). Iterative Methods for Optimization. SIAM. -- Bourdin, B., Francfort, G. A., Marigo, J.-J. (2008). The variational approach to fracture. Springer. diff --git a/packages/akms/src/akms/_bundled/global_nodes/optim-constrained.md b/packages/akms/src/akms/_bundled/global_nodes/optim-constrained.md deleted file mode 100644 index 90c29db..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/optim-constrained.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -id: optim-constrained -title: Constrained Optimization Methods -domain: computational-mechanics -subdomain: optimization -tags: -- optimization -- constrained -- KKT -- lagrange -- penalty -- augmented-lagrangian -- SQP -status: established -confidence: 0.9 -source: hybrid -edges: -- to: optim-unconstrained-basics - type: refines - weight: 0.7 -- to: composite-delamination - type: feeds-into - weight: 0.5 -- to: pf-at1-regularization - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Constrained Optimization Methods - -## Summary - -Constrained optimization in computational mechanics addresses minimization problems subject to equality, inequality, multipoint algebraic, and partial differential equation (PDE) constraints. The mathematical structure relies on Lagrangian formulations, Karush-Kuhn-Tucker (KKT) first-order optimality conditions, and specialized solver strategies including full-space Lagrange-Newton-Krylov (LNK), reduced sequential quadratic programming (RSQP), interior-point barrier methods, linear constraint elimination, and adjoint-based PDE-constrained optimization. - -## 1. Core Concept - -Constrained optimization seeks to minimize an objective functional subject to physical or geometric constraints. Equality constraints (such as finite element state equations, boundary conditions, or linear hanging-node multipoint relationships) and inequality constraints (such as contact non-penetration or damage irreversibility) modify the search space and optimality conditions. Stationarity of the Lagrangian functional leads to saddle-point linear systems (KKT systems) characterized by indefinite block coefficient matrices. In PDE-constrained optimization (PDE-CO), state constraints are coupled with design parameters, where adjoint methods enable efficient gradient evaluation for large parameter dimensions. In non-convex physical simulations, such as interior-point elastodynamics or phase-field fracture, specialized line-search procedures, barrier penalty transformations, and idempotent linear constraint projection matrices ensure robust convergence and kinematic admissibility. - -## 2. Mathematical Formulation - -**kkt-system** -$$ -\begin{bmatrix} W_{xx} & W_{xu} & J_x^T \\ W_{ux} & W_{uu} & J_u^T \\ J_x & J_u & 0 \end{bmatrix} \begin{bmatrix} dx \\ du \\ d\lambda \end{bmatrix} = -\begin{bmatrix} g_x \\ g_u \\ h \end{bmatrix} -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 6.1, p. 388_ - -**saddle-point-equality-constrained** -$$ -\begin{bmatrix} A & B \\ B^T & 0 \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} b \\ c \end{bmatrix} -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 8.4, p. 268_ - -**interior-point-barrier-functional** -$$ -E(x) = \frac{1}{2}(x - \tilde{x})^T M (x - \tilde{x}) + h^2 \Psi(x) + \kappa \sum_{k \in \mathcal{C}} b(d_k(x)) -$$ -_Source: Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf, Section 3, p. 3_ - -**linear-constraint-elimination-system** -$$ -(C^T A C + \text{Id}_c) \hat{x} = C^T (b - A k) -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.2, p. 5_ - -**pde-constrained-adjoint-gradient** -$$ -\frac{d\hat{J}}{d\theta} = -\frac{\partial J}{\partial U} \left(\frac{\partial C}{\partial U}\right)^{-1} \frac{\partial C}{\partial \theta} + \frac{\partial J}{\partial \theta} -$$ -_Source: Xue et al_2023_JAX-FEM.pdf, Section 3, p. 7_ - -**Notation:** -x, u, U represent state or design variables; \lambda, y represent Lagrange multipliers; W, A, H represent Hessian or stiffness matrices; J_a, B, C represent constraint Jacobians or transformation matrices; \phi, J, E represent objective functionals; d_k, \hat{d} represent contact distance and threshold; \kappa represents barrier stiffness. - - -## 3. Algorithmic Implementation - -**lnk-full-space-kkt-solver** -$$ -\begin{algorithmic} -\State $\text{Initialize state } x_0, \text{ design } u_0, \text{ and multiplier } \lambda_0$ -\While{$\|[g_x^T, g_u^T, h^T]^T\| > \text{tol}$} -\State $\text{Evaluate KKT residual } r_k = \begin{bmatrix} g_x + J_x^T \lambda_k \\ g_u + J_u^T \lambda_k \\ h(x_k, u_k) \end{bmatrix}$ -\State $\text{Solve KKT Newton system } \begin{bmatrix} W_{xx} & W_{xu} & J_x^T \\ W_{ux} & W_{uu} & J_u^T \\ J_x & J_u & 0 \end{bmatrix} \begin{bmatrix} dx \\ du \\ d\lambda \end{bmatrix} = -r_k \text{ via preconditioned Krylov-Schwarz}$ -\State $\text{Update iterates } x_{k+1} = x_k + dx, \quad u_{k+1} = u_k + du, \quad \lambda_{k+1} = \lambda_k + d\lambda$ -\EndWhile -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 6.2, p. 388_ - -**interior-point-pncg-solver** -$$ -\begin{algorithmic} -\State $x_0 \leftarrow x_t, \quad \tilde{x} = x_t + h v_t + h^2 M^{-1} f_{\text{ext}}$ -\For{$k = 0 \text{ to } \text{IterMax}$} -\State $\mathcal{C} \leftarrow \text{ComputeConstraintSet}(x_k, \hat{d})$ -\State $g_{k+1}, P_{k+1} \leftarrow \text{ComputeGradientAndPreconditioning}(x_k, \tilde{x}, \mathcal{C})$ -\If{$k == 0$} -\State $\beta_k \leftarrow 0$ -\Else -\EndIf -\State $p_{k+1} \leftarrow -P_{k+1} g_{k+1} + \beta_k p_k$ -\State $\alpha \leftarrow \min\left( \frac{\hat{d}}{2 \|p_{k+1}\|_\infty}, -\frac{g_{k+1}^T p_{k+1}}{p_{k+1}^T H_{k+1} p_{k+1}} \right)$ -\State $x_{k+1} \leftarrow x_k + \alpha p_{k+1}$ -\State $\Delta E \leftarrow -\alpha g_{k+1}^T p_{k+1} - \frac{\alpha^2}{2} p_{k+1}^T H_{k+1} p_{k+1}$ -\If{$\Delta E < \epsilon \Delta E_0$} -\State $\text{Break}$ -\EndIf -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: Implemented natively in Taichi using MeshTaichi for GPU parallel element assembly, diagonal preconditioning P_{k+1}, directional Hessian-vector products p_{k+1}^T H_{k+1} p_{k+1}, and spatial hashing for broad-phase culling. -_Source: Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf, Section 4, p. 5_ - -**linear-constraint-lbfgs-step** -$$ -\begin{algorithmic} -\State $\text{Assemble unconstrained residual } \hat{r}_k = [r_u(x_k); r_d(x_k)]$ -\State $\text{Incorporate nodal constraints into residual } r_k = C^T \hat{r}_k$ -\State $\text{Compute unconstrained search direction } \hat{p}_k = -H_k^0 r_k \text{ via L-BFGS two-loop recursion}$ -\State $\text{Enforce constraint kinematics on search direction } p_k = C \hat{p}_k$ -\State $\text{Find step length } \alpha_k > 0 \text{ satisfying strong Wolfe conditions}$ -\State $\text{Update solution } x_{k+1} = x_k + \alpha_k p_k$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.2, p. 6_ - - -## 4. Known Pitfalls - -- **rsqp-reduced-hessian-scaling-bottleneck**: Reduced Sequential Quadratic Programming (RSQP) requires solving m linear systems with the state Jacobian J_x to form the reduced Hessian H at each design iteration. For large-scale problems where design dimension m scales with state dimension n, exact RSQP becomes computationally prohibitive, while quasi-Newton RSQP suffers from slow convergence O(m^p) and loss of scalability. _(Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 6.2, pp. 388-389)_ -- **barrier-step-overshoot-intersection**: In interior-point collision and contact simulations, unconstrained Newton or conjugate gradient step lengths can cause vertex displacements exceeding the barrier threshold d_hat, leading to undetected primitive interpenetration before contact repulsion is activated. Capping step size by alpha_upper = d_hat / (2 ||p||_inf) prevents mesh interpenetration. _(Source: Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf, Section 4.2, p. 6)_ -- **non-convex-lagrangian-indefiniteness**: The KKT matrix arising from constrained optimization is inherently indefinite due to zero diagonal blocks for Lagrange multipliers, preventing direct application of standard positive-definite linear CG solvers without preconditioning or Schur complement transformations. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 8.4, p. 268; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 6.1, p. 388)_ - -## References - -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf -- Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf -- IterMethBook_2ndEd.pdf.pdf -- Xue et al_2023_JAX-FEM.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/optim-lbfgs-fem.md b/packages/akms/src/akms/_bundled/global_nodes/optim-lbfgs-fem.md deleted file mode 100644 index 1259a9c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/optim-lbfgs-fem.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: optim-lbfgs-fem -title: L-BFGS for Nonlinear FEM -domain: computational-mechanics -subdomain: optimization -tags: -- optimization -- lbfgs -- FEM -- preconditioned-lbfgs -- hybrid-newton -status: established -confidence: 0.9 -source: hybrid -edges: -- to: optim-lbfgs - type: refines - weight: 0.7 -- to: optim-as-solver - type: refines - weight: 0.7 -- to: pf-monolithic-bfgs - type: feeds-into - weight: 0.5 -- to: optim-newton-krylov - type: contradicts - weight: 0.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# L-BFGS for Nonlinear FEM - -## Summary - -Limited-memory Broyden-Fletcher-Goldfarb-Shanno (L-BFGS) for nonlinear finite element analysis replaces full Newton-Raphson iterations to solve coupled, non-convex boundary value problems without forming or factorizing dense Hessian matrices. By maintaining a memory horizon of m vector pairs (solution step s_k and residual increment y_k), L-BFGS calculates search directions via two-loop recursion. Combined with initial inverse Hessian scaling (such as block-diagonal stiffness matrices or matrix-free multigrid V-cycles), idempotent linear constraint projection matrices for hanging nodes and boundary conditions, and strong Wolfe or gradient-based line searches, L-BFGS achieves robust superlinear convergence in non-convex mechanics. - -## 1. Core Concept - -In finite element discretizations of non-convex mechanical problems—such as phase-field brittle fracture or large-deformation hyperelasticity—the true tangent stiffness matrix (Hessian) can become indefinite or non-symmetric, causing standard Newton-Raphson solvers to diverge during snap-back or rapid crack propagation. Classical BFGS quasi-Newton updates preserve symmetry and positive definiteness via rank-two updates, but introduce fully dense matrices that destroy finite element sparsity. L-BFGS circumvents dense matrix storage by representing the inverse Hessian implicitly using m recent vector pairs s_k = x_{k+1} - x_k and y_k = r_{k+1} - r_k. An initial scaling operator H_0^k—typically chosen as a matrix-free multigrid preconditioner or the inverse of the uncoupled block-diagonal stiffness matrix \hat{K} = \text{diag}(K_{uu}, K_{dd})—is updated using two-loop recursion. To enforce algebraic nodal constraints (such as hanging nodes from adaptive mesh refinement and Dirichlet boundary conditions x = C x + k with C^2 = C), residual vectors are pre-multiplied by C^T and search directions are post-multiplied by C, guaranteeing descent and kinematic admissibility. - -## 2. Mathematical Formulation - -**lbfgs-two-loop-search-direction** -$$ -p_k = -H_k r_k -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS method with adaptive mesh refinement.pdf, Section 3.2, p. 11_ - -**lbfgs-secant-and-curvature-condition** -$$ -H_{k+1} = (I - \rho_k s_k y_k^T) H_k (I - \rho_k y_k s_k^T) + \rho_k s_k s_k^T, \quad \rho_k = \frac{1}{y_k^T s_k} -$$ -_Source: Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 5_ - -**matrix-free-multigrid-initial-hessian** -$$ -H_0^k = M_{\text{MG}}^{-1} -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Section III.A, p. 3_ - -**constrained-lbfgs-projection** -$$ -r_k = C^T \hat{r}_k, \quad p_k = C \hat{p}_k -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS method with adaptive mesh refinement.pdf, Section 3.2, p. 11_ - -**Notation:** -x represents the global primal DOF solution vector (displacements and internal state variables); r represents the residual vector; p represents the search direction; s_k represents the solution step vector; y_k represents the residual change vector; H_k represents the inverse Hessian approximation matrix/operator; C represents the linear constraint transformation matrix; \alpha_k represents the line search step length parameter. - - -## 3. Algorithmic Implementation - -**lbfgs-two-loop-recursion-algorithm** -$$ -\begin{algorithmic} -\State $q \leftarrow r_k, \quad \hat{m} \leftarrow \min(m, k)$ -\For{$i = k - 1 \text{ down to } k - \hat{m}$} -\State $\rho_i \leftarrow \frac{1}{y_i^T s_i}$ -\State $\alpha_i \leftarrow \rho_i s_i^T q$ -\State $q \leftarrow q - \alpha_i y_i$ -\EndFor -\State $p_k \leftarrow H_0^k q \quad \text{where } H_0^k = \hat{K}^{-1} = \begin{bmatrix} K_{uu}^{-1} & 0 \\ 0 & K_{dd}^{-1} \end{bmatrix}$ -\For{$i = k - \hat{m} \text{ to } k - 1$} -\State $\beta \leftarrow \rho_i y_i^T p_k$ -\State $p_k \leftarrow p_k + s_i (\alpha_i - \beta)$ -\EndFor -\State $p_k \leftarrow -p_k$ -\Return $p_k$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS method with adaptive mesh refinement.pdf, Section 3.2, p. 11, Algorithm 1_ - -**constrained-lbfgs-monolithic-step** -$$ -\begin{algorithmic} -\State $\text{Assemble global FE residual } \hat{r}_k = [r_u(x_k); r_d(x_k)]$ -\State $r_k = C^T \hat{r}_k \quad \text{(filter residual at constrained nodes)}$ -\State $\text{Compute search direction } \hat{p}_k = -H_k r_k \text{ via L-BFGS two-loop recursion}$ -\State $p_k = C \hat{p}_k \quad \text{(enforce constraint kinematics)}$ -\State $\text{Determine step size } \alpha_k > 0 \text{ satisfying strong Wolfe conditions } \Pi(x_k + \alpha_k p_k) \le \Pi(x_k) + c_1 \alpha_k r_k^T p_k$ -\State $x_{k+1} = x_k + \alpha_k p_k$ -\State $s_k = x_{k+1} - x_k, \quad y_k = r_{k+1} - r_k$ -\State $\text{Update L-BFGS memory buffer with vector-pair } \{s_k, y_k\} \text{ (evicting oldest pair if } k > m\text{)}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS method with adaptive mesh refinement.pdf, Section 3.2, p. 12, Algorithm 2_ - - -## 4. Known Pitfalls - -- **lbfgs-dense-matrix-storage-exhaustion**: Classical BFGS updates add rank-two outer product modifications y_k y_k^T and B_k s_k (B_k s_k)^T to sparse FE stiffness matrices. This destroys finite element matrix sparsity and converts sparse systems into fully dense n \times n matrices, causing severe memory allocation failure on large 2D/3D meshes. L-BFGS circumvents this by storing only m vector pairs \{s_i, y_i\} (typically m = 5 to 10). _(Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS method with adaptive mesh refinement.pdf, Section 3.1, pp. 10-11)_ -- **non-convex-curvature-breakdown**: For non-convex mechanical energy functionals (such as phase-field damage formulations during snap-back or crack initiation), the curvature condition s_k^T y_k > 0 can be violated. Performing standard BFGS matrix updates when s_k^T y_k \le 0 destroys the positive definiteness of H_{k+1}, causing search direction breakdown unless guarded by strong Wolfe line search or curvature-filtered modified updates. _(Source: Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, pp. 5-6)_ -- **premature-energy-plateau-termination**: In brutal crack propagation simulations, total energy functional \Pi(x) can reach a flat numerical plateau after several hundred L-BFGS iterations while absolute residual norms ||r_u||_2 and ||r_d||_2 remain unacceptably large (>10^{-3}). Terminating L-BFGS based solely on energy flattening or loose increment thresholds under-predicts crack growth; strict residual-based convergence criteria are required. _(Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS method with adaptive mesh refinement.pdf, Section 4.1, pp. 13-14)_ - -## References - -- Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS method with adaptive mesh refinement.pdf -- Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf -- Wu et al. - 2020 - On the BFGS monolithic algorithm for the unified phase field damage theory.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p-Multigrid.pdf -- Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/optim-lbfgs.md b/packages/akms/src/akms/_bundled/global_nodes/optim-lbfgs.md deleted file mode 100644 index 08f6bd5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/optim-lbfgs.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: optim-lbfgs -title: 'L-BFGS Algorithm: Two-Loop Recursion' -domain: computational-mechanics -subdomain: optimization -tags: -- optimization -- lbfgs -- quasi-newton -- two-loop -- liu-nocedal -status: established -confidence: 0.9 -source: hybrid -edges: -- to: optim-unconstrained-basics - type: refines - weight: 0.7 -- to: optim-line-search - type: requires - weight: 1.0 -- to: optim-lbfgs-fem - type: feeds-into - weight: 0.5 -- to: pf-monolithic-bfgs - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# L-BFGS Algorithm: Two-Loop Recursion - -## Summary - -The limited-memory Broyden-Fletcher-Goldfarb-Shanno (L-BFGS) algorithm is a quasi-Newton optimization method designed for large-scale non-convex systems. By replacing full dense inverse Hessian storage with a two-loop recursion operating on a sliding window of m recent displacement and residual vector pairs, L-BFGS computes effective search directions in O(m n) time and memory per iteration while maintaining superlinear convergence. - -## 1. Core Concept - -Quasi-Newton methods approximate second-order curvature without evaluating or factorizing full Hessian matrices. In classical BFGS, rank-two updates accumulate curvature information from differences between consecutive iterates s_k = x_{k+1} - x_k and residual gradients y_k = r_{k+1} - r_k. However, classical BFGS generates dense n x n matrices, rendering it intractable for large finite element or continuum mechanics problems. The L-BFGS algorithm circumvents dense matrix storage by representing the inverse Hessian implicitly through a two-loop recursion that applies m vector pairs {s_i, y_i}. Coupled with initial inverse Hessian scaling H_0^k and line search strategies (such as strong Wolfe conditions), L-BFGS enforces the curvature condition s_k^T y_k > 0 to maintain positive definiteness and guaranteed descent directions across non-convex mechanical energy landscapes. - -## 2. Mathematical Formulation - -**lbfgs-search-direction** -$$ -p_k = -H_k r_k -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.2, p. 11_ - -**bfgs-inverse-hessian-update** -$$ -H_{k+1} = (I - \rho_k s_k y_k^T) H_k (I - \rho_k y_k s_k^T) + \rho_k s_k s_k^T -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 5_ - -**curvature-condition** -$$ -s_k^T y_k > 0 -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 6_ - -**initial-hessian-scaling** -$$ -H_0^k = \frac{s_{k-1}^T y_{k-1}}{y_{k-1}^T y_{k-1}} I -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.2, p. 11_ - -**modified-nonconvex-lbfgs-update** -$$ -H_{k+1} = \begin{cases} (I - \rho_k s_k y_k^T) H_k (I - \rho_k y_k s_k^T) + \rho_k s_k s_k^T, & \text{if } s_k^T y_k > 0 \\ H_k, & \text{otherwise} \end{cases} -$$ -_Source: Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 6_ - -**Notation:** -x represents the optimization solution vector; r represents the gradient/residual vector; p represents the search direction vector; s_k represents the solution step vector x_{k+1} - x_k; y_k represents the residual vector increment r_{k+1} - r_k; H_k represents the inverse Hessian operator; \rho_k represents the curvature weighting parameter 1 / (y_k^T s_k); m represents the memory buffer depth; \hat{m} represents min(m, k). - - -## 3. Algorithmic Implementation - -**lbfgs-two-loop-recursion** -$$ -\begin{algorithmic} -\State $q \leftarrow r_k, \quad \hat{m} \leftarrow \min(m, k)$ -\For{$i = k - 1 \text{ down to } k - \hat{m}$} -\State $\rho_i \leftarrow \frac{1}{y_i^T s_i}$ -\State $\alpha_i \leftarrow \rho_i s_i^T q$ -\State $q \leftarrow q - \alpha_i y_i$ -\EndFor -\State $p_k \leftarrow H_0^k q$ -\For{$i = k - \hat{m} \text{ to } k - 1$} -\State $\beta \leftarrow \rho_i y_i^T p_k$ -\State $p_k \leftarrow p_k + s_i (\alpha_i - \beta)$ -\EndFor -\State $p_k \leftarrow -p_k$ -\Return $p_k$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.2, p. 11, Algorithm 1; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 7, Algorithm 2_ - -**lbfgs-outer-iteration-driver** -$$ -\begin{algorithmic} -\State $\text{Initialize } x_0, \text{ memory horizon } m, \text{ and buffer } \mathcal{S} = \emptyset$ -\For{$k = 0, 1, 2, \dots \text{ until } \|r_k\|_2 < \text{tol}$} -\State $\text{Evaluate residual } r_k = \nabla f(x_k)$ -\State $\text{Compute search direction } p_k \text{ via L-BFGS two-loop recursion}$ -\State $\text{Find step length } \alpha_k > 0 \text{ satisfying strong Wolfe conditions}$ -\State $x_{k+1} = x_k + \alpha_k p_k$ -\State $s_k = x_{k+1} - x_k, \quad y_k = r_{k+1} - r_k$ -\If{$s_k^T y_k > 0$} -\State $\text{Store pair } \{s_k, y_k\} \text{ in } \mathcal{S} \text{ (evicting oldest if } |\mathcal{S}| > m\text{)}$ -\EndIf -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.2, p. 12, Algorithm 2; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 7, Algorithm 2_ - - -## 4. Known Pitfalls - -- **dense-hessian-memory-explosion**: Storing explicit BFGS inverse Hessian updates in large-scale discretizations requires dense n x n matrices, leading to quadratic O(n^2) memory complexity that quickly exhausts available RAM. L-BFGS avoids explicit matrix storage by maintaining only m vector pairs {s_i, y_i}, reducing memory complexity to O(mn). _(Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, pp. 10-11; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 6)_ -- **loss-of-positive-definiteness-nonconvex**: In non-convex optimization, step updates can yield negative curvature s_k^T y_k <= 0. Updating the quasi-Newton inverse Hessian under negative curvature destroys positive definiteness and produces non-descent search directions. Skipping the update when s_k^T y_k <= 0 or enforcing strong Wolfe line search conditions guarantees s_k^T y_k > 0. _(Source: Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, pp. 5-6; Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10)_ -- **insufficient-memory-horizon-sluggish-convergence**: Setting the memory buffer depth m too small (e.g., m = 0) discards crucial curvature history, causing L-BFGS to degrade toward unconditioned steepest descent with extremely high iteration counts. Selecting m between 5 and 10 restores quasi-Newton superlinear convergence without incurring high memory overhead. _(Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 4.2, p. 18; Wu et al. - 2020 - On the BFGS monolithic algorithm for the unified phase field damage theory.pdf, Section 3.3, p. 10)_ - -## References - -- Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf -- Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf -- Wu et al. - 2020 - On the BFGS monolithic algorithm for the unified phase field damage theory.pdf -- Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/optim-line-search.md b/packages/akms/src/akms/_bundled/global_nodes/optim-line-search.md deleted file mode 100644 index 70a4ff7..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/optim-line-search.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -id: optim-line-search -title: Line Search Strategies -domain: computational-mechanics -subdomain: optimization -tags: -- optimization -- line-search -- armijo -- wolfe -- backtracking -- cubic-interpolation -status: established -confidence: 0.9 -source: hybrid -edges: -- to: optim-unconstrained-basics - type: refines - weight: 0.7 -- to: optim-lbfgs - type: feeds-into - weight: 0.5 -- to: optim-newton-krylov - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Line Search Strategies - -## Summary - -Line search strategies in computational mechanics determine the step length parameter \alpha_k along a computed search direction p_k to ensure globalization, numerical stability, and satisfaction of curvature conditions. Essential strategies range from basic Armijo backtracking to strong Wolfe conditions, Moré-Thuente cubic interpolation, interior-point upper-bounded secant updates, and gradient-based quasi-Newton line searches for non-variational mechanics. - -## 1. Core Concept - -Line search algorithms scale descent search directions p_k produced by Newton-Raphson, quasi-Newton (BFGS/L-BFGS), or preconditioned nonlinear conjugate gradient (PNCG) solvers to update primal solution iterates x_{k+1} = x_k + \alpha_k p_k. In unconstrained optimization, line search prevents divergence, overshooting, and snap-back instability. Simple Armijo backtracking enforces sufficient decrease of objective functionals. However, in quasi-Newton methods, line search must also satisfy the curvature condition s_k^T y_k > 0 (via Wolfe or strong Wolfe conditions) to guarantee positive definiteness of inverse Hessian updates. For non-variational or history-dependent mechanical models (such as phase-field fracture with damage irreversibility history variables or non-conservative hyperelasticity), global energy functionals do not exist or mismatch residual gradients. In these contexts, gradient-based secular line searches solve g(x_k + \alpha p_k)^T p_k = 0 via one-pass secant or quasi-Newton iterations, achieving robust convergence without evaluating energy functionals. - -## 2. Mathematical Formulation - -**armijo-sufficient-decrease** -$$ -f(x_k + \alpha_k p_k) \le f(x_k) + c_1 \alpha_k \nabla f(x_k)^T p_k -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10; Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.1, p. 242_ - -**strong-wolfe-conditions** -$$ -f(x_k + \alpha_k p_k) \le f(x_k) + c_1 \alpha_k \nabla f(x_k)^T p_k, \quad |\nabla f(x_k + \alpha_k p_k)^T p_k| \le c_2 |\nabla f(x_k)^T p_k| -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10; Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.1, p. 242_ - -**quasi-newton-secular-line-search** -$$ -\Delta \lambda_l = -\Delta \lambda_{l-1} \frac{g_l^T p_k}{y_{l-1}^T p_k}, \quad \lambda_{l+1} = \lambda_l + \Delta \lambda_l -$$ -_Source: Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2.1, p. 7_ - -**interior-point-quadratic-line-search** -$$ -\alpha_k = \min\left( \frac{\hat{d}}{2 \|p_k\|_\infty}, -\frac{g_k^T p_k}{p_k^T H_k p_k} \right) -$$ -_Source: Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf, Section 4.3, p. 6_ - -**Notation:** -x represents solution vector; f represents objective energy functional; g, r represent residual gradient vectors; p, d represent search direction vectors; \alpha, s, \lambda represent step length parameters; c_1, c_2, \delta, \sigma represent line search threshold parameters; \hat{d} represents contact barrier threshold distance. - - -## 3. Algorithmic Implementation - -**armijo-backtracking-line-search** -$$ -\begin{algorithmic} -\State $\text{Initialize step size } s = 1, \text{ decay factor } \tau \in (0, 1), \text{ and parameter } c_1 \in (0, 1)$ -\While{$f(x_k + s p_k) > f(x_k) + c_1 s \nabla f(x_k)^T p_k$} -\State $s \leftarrow \tau s$ -\EndWhile -\Return $\alpha_k = s$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.4.1, p. 364_ - -**more-thuente-strong-wolfe-line-search** -$$ -\begin{algorithmic} -\State $\text{Set initial step } \alpha_0 = 1, \text{ tolerances } c_1 = 10^{-4}, c_2 = 0.9$ -\State $\text{Define scalar function } \phi(\alpha) = f(x_k + \alpha p_k) \text{ with derivative } \phi'(\alpha) = \nabla f(x_k + \alpha p_k)^T p_k$ -\While{$\phi(\alpha_l) > \phi(0) + c_1 \alpha_l \phi'(0) \text{ or } |\phi'(\alpha_l)| > c_2 |\phi'(0)|$} -\State $\text{Update trial step } \alpha_{l+1} \text{ via cubic/quadratic interpolation in interval } I_l \text{ satisfying Wolfe conditions}$ -\State $l \leftarrow l + 1$ -\EndWhile -\Return $\alpha_k = \alpha_l$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.2, p. 11_ - -**quasi-newton-gradient-line-search** -$$ -\begin{algorithmic} -\State $x_k, p_k, g_k \leftarrow \text{Iterate, search direction, gradient}$ -\State $\lambda_0 = 1, \quad g_1 = g(x_k + \lambda_0 p_k), \quad y_0 = g_1 - g_k$ -\If{$p_k^T y_0 > \text{TOL}_{\text{act}}^{\text{LS}}$} -\For{$l = 1 \text{ to } l_{\text{max}}$} -\State $\Delta \lambda_l \leftarrow -\Delta \lambda_{l-1} \frac{g_l^T p_k}{y_{l-1}^T p_k}$ -\State $\lambda_{l+1} \leftarrow \lambda_l + \Delta \lambda_l$ -\If{$|\Delta \lambda_l| \le \text{TOL}_{\text{LS}}$} -\State $\text{Break}$ -\EndIf -\State $g_{l+1} \leftarrow g(x_k + \lambda_{l+1} p_k), \quad y_l \leftarrow g_{l+1} - g_l$ -\EndFor -\Else -\State $\lambda_k \leftarrow 1$ -\EndIf -\Return $\alpha_k = \lambda_k$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2.1, p. 8, Algorithm 3_ - - -## 4. Known Pitfalls - -- **non-variational-energy-line-search-failure**: In non-variational mechanical formulations (such as phase-field fracture incorporating history variables for damage irreversibility), the energy functional becomes a pseudo-energy whose value does not monotonically decrease with residual gradients. Line search methods based strictly on objective energy decrease (e.g. Armijo or energy-minimized interpolation) can select incorrect step lengths, cause line search stalling, or lead to algorithm divergence. Gradient-based secular line search solving g(x_k + \lambda p_k)^T p_k = 0 resolves this issue without evaluating energy functionals. _(Source: Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2.1, pp. 6-7)_ -- **armijo-backtracking-violates-curvature-condition**: Simple Armijo backtracking line search only enforces sufficient decrease of the objective function and does not satisfy the curvature condition s_k^T y_k > 0. In quasi-Newton methods (such as BFGS or L-BFGS), updating inverse Hessian approximations under steps that violate curvature condition s_k^T y_k > 0 produces indefinite matrices and non-descent directions, causing solver breakdown. Strong Wolfe or modified curvature-skipped updates must be enforced. _(Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 6)_ -- **line-search-computational-overhead-in-fft-mechanics**: In FFT-based computational micromechanics, line search procedures require multiple expensive material law evaluations and stress updates per iteration. Because condensed energy functionals are typically not computed explicitly in FFT solvers (only stress gradients are available), naive line search doubled the execution time compared to fixed-step fast gradient methods. _(Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2, pp. 241-242)_ - -## References - -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf -- Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf -- Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf -- Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/optim-newton-krylov.md b/packages/akms/src/akms/_bundled/global_nodes/optim-newton-krylov.md deleted file mode 100644 index 7d4db0f..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/optim-newton-krylov.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: optim-newton-krylov -title: Newton-Krylov Methods (Inexact Newton) -domain: computational-mechanics -subdomain: optimization -tags: -- optimization -- newton-krylov -- JFNK -- inexact-newton -- eisenstat-walker -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-jfnk - type: refines - weight: 0.7 -- to: solver-gmres-algorithm - type: requires - weight: 1.0 -- to: optim-line-search - type: requires - weight: 1.0 -- to: optim-lbfgs - type: contradicts - weight: 0.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Newton-Krylov Methods (Inexact Newton) - -## Summary - -Newton-Krylov methods (inexact Newton) solve large-scale non-convex systems of nonlinear algebraic equations arising in computational mechanics by coupling outer Newton updates with inner Krylov subspace iterative solvers. By exploiting matrix-free directional derivatives (or automatic differentiation) to compute Jacobian-vector products J v without forming or factorizing dense global Jacobians, Jacobian-Free Newton-Krylov (JFNK) methods achieve superlinear convergence while reducing memory overhead. - -## 1. Core Concept - -Newton-Krylov methods address non-autonomous, non-convex, and coupled physical problems where assembling and factorizing full tangent stiffness matrices (Jacobians) is computationally prohibitive or analytically intractable. In an inexact Newton framework, the linearized Newton system J(u_k) du_k = -F(u_k) is solved approximately by a Krylov subspace method (such as GMRES or CG) until the linear residual satisfies an inexact termination condition ||J(u_k) du_k + F(u_k)||_2 <= \eta_k ||F(u_k)||_2, governed by a forcing term \eta_k. JFNK evaluates matrix-vector products J v via finite difference directional derivatives of the nonlinear residual functional F(u + \epsilon v) or via reverse-mode automatic differentiation. Robustness is maintained by combining inexact Newton updates with preconditioning operators (such as physics-based splitting, domain decomposition additive Schwarz, or multigrid V-cycles) and globalization strategies (such as pseudo-transient continuation or line search). - -## 2. Mathematical Formulation - -**inexact-newton-condition** -$$ -\|J(u_k) du_k + F(u_k)\|_2 \le \eta_k \|F(u_k)\|_2 -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3.2, p. 363_ - -**jfnk-jacobian-vector-directional-derivative** -$$ -J(u) v \approx \frac{F(u + \epsilon v) - F(u)}{\epsilon} -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3, p. 362_ - -**jfnk-perturbation-parameter-scaling** -$$ -\epsilon = \frac{\sqrt{(1 + \|u\|_2) \epsilon_{\text{mach}}}}{\|v\|_2} -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3.1, p. 363_ - -**preconditioned-jfnk-right-system** -$$ -(J P^{-1}) (P du) = -F(u) -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 3, p. 367_ - -**Notation:** -u represents the solution state vector; F(u) represents the nonlinear residual function; J represents the exact Jacobian operator; du represents the Newton update step; v represents a Krylov vector; \eta_k represents the forcing term parameter; \epsilon represents the finite difference perturbation parameter; P^{-1} represents the preconditioning operator. - - -## 3. Algorithmic Implementation - -**inexact-newton-krylov-outer-inner-solver** -$$ -\begin{algorithmic} -\State $\text{Initialize solution } u_0, \text{ nonlinear tolerance } \text{tol}_{\text{res}}, \text{ and forcing sequence } \{\eta_k\}$ -\For{$k = 0, 1, 2, \dots \text{ until } \|F(u_k)\|_2 < \text{tol}_{\text{res}} \|F(u_0)\|_2$} -\State $\text{Evaluate residual vector } F(u_k)$ -\State $\text{Solve linear system } J(u_k) du_k = -F(u_k) \text{ inexactly via GMRES to satisfy } \|J(u_k) du_k + F(u_k)\|_2 \le \eta_k \|F(u_k)\|_2$ -\State $\text{Evaluate matrix-vector products } J(u_k) v \text{ matrix-free via } \frac{F(u_k + \epsilon v) - F(u_k)}{\epsilon}$ -\State $\text{Determine step size } s_k \in (0, 1] \text{ via line search or pseudo-transient continuation}$ -\State $u_{k+1} = u_k + s_k du_k$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.1-2.3, pp. 359-364_ - - -## 4. Known Pitfalls - -- **jfnk-oversolving-inexact-newton-step**: Solving the linear Newton correction system J(u_k) du_k = -F(u_k) to an overly tight relative linear tolerance (\eta_k \ll 1) during early outer iterations wastes Krylov iterations calculating an exact solution for an inaccurate far-from-root linearization. Setting adaptive forcing terms \eta_k avoids oversolving. _(Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3.2, p. 364)_ -- **finite-difference-perturbation-cancellation-noise**: Evaluating matrix-free directional derivatives via J v \approx (F(u + \epsilon v) - F(u)) / \epsilon requires careful scaling of \epsilon. Choosing \epsilon too large introduces severe truncation error, while choosing \epsilon too small causes floating-point roundoff cancellation, destroying Krylov subspace orthogonality. _(Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3.1, pp. 362-363)_ -- **non-monotone-discontinuity-stagnation**: In non-linear systems with sharp spatial features, shocks, or non-smooth material constitutive laws, finite difference Frechet derivative estimates J v become noisy or non-monotone, causing Newton-Krylov line searches to stagnate or fail to converge. _(Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3, p. 362)_ - -## References - -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- Xue et al_2023_JAX-FEM.pdf -- Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf -- IterMethBook_2ndEd.pdf.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/optim-nonlinear-cg.md b/packages/akms/src/akms/_bundled/global_nodes/optim-nonlinear-cg.md deleted file mode 100644 index dc7ebdf..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/optim-nonlinear-cg.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -id: optim-nonlinear-cg -title: Nonlinear Conjugate Gradient -domain: computational-mechanics -subdomain: optimization -tags: -- optimization -- nonlinear-CG -- fletcher-reeves -- polak-ribiere -- hestenes-stiefel -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-cg-algorithm - type: refines - weight: 0.7 -- to: optim-unconstrained-basics - type: refines - weight: 0.7 -- to: optim-line-search - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Nonlinear Conjugate Gradient - -## Summary - -The nonlinear conjugate gradient (NCG) method generalizes the linear conjugate gradient algorithm to unconstrained nonlinear optimization problems in computational mechanics. By generating search directions using gradient vectors and momentum weighting parameters (such as Fletcher-Reeves, Polak-Ribière, or Dai-Kou), NCG operates with a minimal memory footprint (requiring storage of only 2 to 3 vector fields) and avoids forming or factorizing dense global Hessian matrices. - -## 1. Core Concept - -Nonlinear conjugate gradient methods solve large-scale non-convex optimization problems arising in continuum mechanics, FFT-based micromechanics, and interior-point real-time hyperelasticity. Unlike linear CG where conjugate directions are orthogonalized with respect to a constant symmetric positive-definite matrix A, NCG computes search directions d_k = -g_k + \beta_{k-1} d_{k-1} using nonlinearly updated scalar momentum parameters \beta_k. Popular \beta_k formulations include Fletcher-Reeves (FR), Polak-Ribière-Polyak (PRP), Hestenes-Stiefel (HS), Dai-Yuan (DY), and Dai-Kou (DK). Continuous dynamic analysis reveals that Fletcher-Reeves NCG corresponds to a second-order Newtonian dynamical system with state-dependent nonlinear damping determined by residual gradient reduction rates. Combined with Jacobi preconditioning and one-pass step size selection, NCG provides a memory-efficient, parameter-choice-free alternative to quasi-Newton and Newton-Raphson solvers for high-dimensional discretizations. - -## 2. Mathematical Formulation - -**fletcher-reeves-beta** -$$ -\beta_k^{\text{FR}} = \frac{\|g_{k+1}\|_2^2}{\|g_k\|_2^2} -$$ -_Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.1, p. 242_ - -**polak-ribiere-beta** -$$ -\beta_k^{\text{PRP}} = \frac{g_{k+1}^T (g_{k+1} - g_k)}{\|g_k\|_2^2} -$$ -_Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.1, p. 242_ - -**dai-kou-beta** -$$ -\beta_k^{\text{DK}} = \frac{g_{k+1}^T y_k}{y_k^T p_k} - \frac{y_k^T y_k}{y_k^T p_k} \frac{p_k^T g_{k+1}}{y_k^T p_k} -$$ -_Source: Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf, Section 4.1, p. 5_ - -**fletcher-reeves-dynamical-system** -$$ -\ddot{x} - \frac{2 \langle \nabla f(x), \nabla^2 f(x) \dot{x} \rangle}{\|\nabla f(x)\|^2} \dot{x} = -\nabla f(x) -$$ -_Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.3, p. 244_ - -**Notation:** -x represents solution vector; f represents objective functional; g represents gradient vector; d, p represent search direction vectors; \beta represents momentum weighting parameter; \alpha represents step length parameter; y_k represents gradient increment g_{k+1} - g_k; P represents Jacobi preconditioning matrix. - - -## 3. Algorithmic Implementation - -**fletcher-reeves-ncg-fft** -$$ -\begin{algorithmic} -\State $x_0 \leftarrow \text{Initial guess}, \quad d_{-1} \leftarrow 0, \quad g_0 \leftarrow \nabla f(x_0)$ -\For{$k = 0, 1, 2, \dots \text{ until } \|g_k\|_2 < \text{tol}$} -\If{$k == 0$} -\State $\beta_k^{\text{FR}} \leftarrow 0$ -\Else -\EndIf -\State $d_k \leftarrow -g_k + \beta_k^{\text{FR}} d_{k-1}$ -\State $\alpha_k \leftarrow \text{Determine via line search or fixed step } \alpha = \frac{2}{c_- + c_+}$ -\State $x_{k+1} \leftarrow x_k + \alpha_k d_k, \quad g_{k+1} \leftarrow \nabla f(x_{k+1})$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.1, p. 242; Section 3, p. 246, Algorithm 1_ - -**preconditioned-dai-kou-ncg** -$$ -\begin{algorithmic} -\State $x_0 \leftarrow x_t, \quad p_0 \leftarrow -P_0 g_0 \quad \text{where } g_0 = \nabla E(x_0)$ -\For{$k = 0 \text{ to } \text{IterMax}$} -\State $g_{k+1}, P_{k+1} \leftarrow \text{Compute gradient and Jacobi preconditioner } P_{k+1} = \text{diag}(H_{k+1})^{-1}$ -\State $y_k \leftarrow g_{k+1} - g_k$ -\State $\beta_k^{\text{DK}} \leftarrow \frac{g_{k+1}^T P_{k+1} y_k}{y_k^T p_k} - \frac{y_k^T P_{k+1} y_k}{y_k^T p_k} \frac{p_k^T g_{k+1}}{y_k^T p_k}$ -\State $p_{k+1} \leftarrow -P_{k+1} g_{k+1} + \beta_k^{\text{DK}} p_k$ -\State $\alpha \leftarrow \min\left( \frac{\hat{d}}{2 \|p_{k+1}\|_\infty}, -\frac{g_{k+1}^T p_{k+1}}{p_{k+1}^T H_{k+1} p_{k+1}} \right)$ -\State $x_{k+1} \leftarrow x_k + \alpha p_{k+1}$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: Implemented natively in Taichi using MeshTaichi for parallel element assembly, Jacobi diagonal preconditioning P_{k+1}, and parallel vector dot products. -_Source: Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf, Section 4.2, p. 5, Algorithm 1_ - - -## 4. Known Pitfalls - -- **ncg-lack-of-explicit-convergence-rate**: Unlike linear conjugate gradient or Newton methods, nonlinear conjugate gradient methods lack general theoretical proofs of superlinear convergence rates; for general non-convex objective functionals, convergence theorems typically establish asymptotic residual vanishing \lim_{k \to \infty} \|g_k\| = 0 without explicit rate bounds. _(Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.1, p. 242)_ -- **line-search-overhead-in-fft-micromechanics**: Standard NCG implementations require line search evaluations (such as Wolfe conditions) that evaluate objective function values. In FFT-based computational micromechanics, condensed energy functionals are typically unavailable (only stress gradients are computed), making line search costly or intractable unless replaced by fixed step bounds or gradient-based updates. _(Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 1, p. 240; Section 2.1, p. 241)_ -- **restarting-inefficiency**: Periodic restarting strategies (e.g., resetting search directions to steepest descent every n iterations) do not improve efficiency in FFT micromechanics or fast gradient methods; in practice, restarting schemes require roughly twice the iteration count compared to NCG solvers with optimal parameter selection. _(Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 1, p. 240)_ - -## References - -- Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf -- Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf -- IterMethBook_2ndEd.pdf.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/optim-trust-region.md b/packages/akms/src/akms/_bundled/global_nodes/optim-trust-region.md deleted file mode 100644 index 5ab9d5c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/optim-trust-region.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: optim-trust-region -title: Trust Region Methods -domain: computational-mechanics -subdomain: optimization -tags: -- optimization -- trust-region -- dogleg -- steihaug -- cauchy-point -status: established -confidence: 0.9 -source: hybrid -edges: -- to: optim-unconstrained-basics - type: refines - weight: 0.7 -- to: optim-line-search - type: contradicts - weight: 0.0 -- to: optim-newton-krylov - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Trust Region Methods - -## Summary - -Trust region methods provide a robust globalization framework for Newton and Newton-Krylov solvers in computational mechanics by defining a neighborhood around the current iterate where a local Taylor linearization or model approximation is trusted to accurately represent the nonlinear residual. Rather than restricting search steps to a single search direction as in line search methods, trust region approaches search for candidate steps—often formed as linear combinations of candidate directions, including approximate Newton corrections—within a bounded trust radius. In non-convex physical problems, such as fully monolithic phase-field models of fracture, trust region methods prevent divergence during post-peak softening and brutal crack propagation regimes. - -## 1. Core Concept - -Globalization of Newton-Raphson and Jacobian-Free Newton-Krylov (JFNK) methods is essential when initial solution iterates lie far from the root, where full Newton steps cause divergence or stagnation. Trust region globalization replaces line search step-length scaling along a single search direction by searching within a ball or region in which the linear residual model approximation F(u_k) + J(u_k) du \approx F(u_k + du) remains valid. Candidate steps are chosen to ensure residual reduction and robust convergence. In non-convex solid mechanics and phase-field fracture, where energy functionals lack convexity and tangent stiffness matrices become indefinite or ill-conditioned, trust region strategies maintain numerical stability through brutal crack propagation and post-peak softening regimes where standard line search methods frequently fail. - -## 2. Mathematical Formulation - -**trust-region-linear-model-approximation** -$$ -F(u_k) + J(u_k) du \approx F(u_k + du) \quad \text{for } \|du\| \le \Delta_k -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.4.1, p. 364_ - -**trust-region-candidate-step-combination** -$$ -du_k = \sum_{j=1}^p \alpha_j s_j \quad \text{such that } \|du_k\| \le \Delta_k -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.4.1, p. 364_ - -**inexact-newton-trust-region-subproblem** -$$ -\|J(u_k) du_k + F(u_k)\|_2 \le \eta_k \|F(u_k)\|_2 \quad \text{subject to } \|du_k\| \le \Delta_k -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3.2, p. 363; Section 2.4.1, p. 364_ - -**Notation:** -u represents the solution state vector; F(u) represents the nonlinear residual vector; J(u) represents the Jacobian matrix or matrix-free operator; du represents the solution update step; \Delta_k represents the trust region radius; \eta_k represents the inexact Newton forcing parameter. - - -## 3. Algorithmic Implementation - -**newton-krylov-trust-region-globalization** -$$ -\begin{algorithmic} -\State $\text{Initialize solution } u_0, \text{ initial trust radius } \Delta_0, \text{ and tolerance } \text{tol}$ -\For{$k = 0, 1, 2, \dots \text{ until } \|F(u_k)\|_2 < \text{tol}$} -\State $\text{Evaluate nonlinear residual } F(u_k)$ -\State $\text{Form local linear model } M_k(du) = F(u_k) + J(u_k) du$ -\State $\text{Compute candidate step } du_k \text{ satisfying } \|J(u_k) du_k + F(u_k)\|_2 \le \eta_k \|F(u_k)\|_2 \text{ within trust bound } \|du_k\| \le \Delta_k$ -\If{$\|F(u_k + du_k)\|_2 < \|F(u_k)\|_2$} -\State $u_{k+1} = u_k + du_k \quad \text{(accept step and expand/maintain } \Delta_{k+1} \ge \Delta_k\text{)}$ -\Else -\EndIf -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.4.1, p. 364_ - - -## 4. Known Pitfalls - -- **line-search-stagnation-near-post-peak-softening**: Standard line search Newton-Raphson solvers often stagnate or diverge during post-peak softening or brutal crack propagation in phase-field fracture mechanics due to non-convex energy landscapes and negative directional derivatives. Trust region globalization and recursive multilevel trust region methods preserve convergence where line search fails. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 2, p. 4; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.4.1, p. 364)_ -- **trust-region-model-mismatch-stagnation**: If the trust region radius Delta_k is shrunk too aggressively due to local non-convexity or function evaluation noise, Newton-Krylov solvers take infinitesimally small steps, leading to iteration stagnation without making progress toward the root. _(Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.4.1, p. 364)_ - -## References - -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf -- Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/optim-unconstrained-basics.md b/packages/akms/src/akms/_bundled/global_nodes/optim-unconstrained-basics.md deleted file mode 100644 index ad6020c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/optim-unconstrained-basics.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: optim-unconstrained-basics -title: Unconstrained Optimization Fundamentals -domain: computational-mechanics -subdomain: optimization -tags: -- optimization -- gradient -- hessian -- descent -- wolfe -- kkt-free -status: established -confidence: 0.9 -source: hybrid -edges: -- to: optim-line-search - type: feeds-into - weight: 0.5 -- to: optim-lbfgs - type: feeds-into - weight: 0.5 -- to: optim-newton-krylov - type: feeds-into - weight: 0.5 -- to: optim-trust-region - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Unconstrained Optimization Fundamentals - -## Summary - -Unconstrained optimization in computational mechanics seeks the minimizer of a scalar energy functional or non-convex physical potential without explicit algebraic constraints. Fundamentals encompass first-order stationarity conditions, search direction generation via Newton or quasi-Newton operators, line search globalization satisfying Wolfe conditions, and curvature preservation in non-convex landscapes. - -## 1. Core Concept - -Unconstrained optimization minimizes a continuous scalar objective functional f(x) representing potential energy, compliance, or loss functions. A solution iterate x* satisfies first-order stationarity where the residual gradient r(x*) = \nabla f(x*) = 0. Iterative optimization procedures generate trial steps x_{k+1} = x_k + \alpha_k p_k by computing descent directions p_k = -H_k r_k using true or approximate inverse Hessian operators H_k. In non-convex mechanical formulations (such as phase-field fracture), the true tangent stiffness matrix can become indefinite or singular. Quasi-Newton methods approximate second-order curvature via secant updates B_{k+1} s_k = y_k, where s_k = x_{k+1} - x_k and y_k = r_{k+1} - r_k. Enforcing curvature condition s_k^T y_k > 0 through line search strategies guarantees that updated inverse Hessian approximations H_{k+1} remain positive-definite, ensuring p_k is a valid descent direction. - -## 2. Mathematical Formulation - -**first-order-optimality-condition** -$$ -r(x) = \nabla f(x) = 0 -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 5_ - -**descent-direction-condition** -$$ -\frac{d\phi(0)}{d\alpha} = r_k^T p_k < 0 -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.2, p. 12_ - -**quasi-newton-secant-equation** -$$ -B_{k+1} s_k = y_k \quad \text{or} \quad H_{k+1} y_k = s_k -$$ -_Source: Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 5; Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10_ - -**wolfe-sufficient-decrease-and-curvature** -$$ -f(x_k + \alpha_k p_k) \le f(x_k) + c_1 \alpha_k r_k^T p_k, \quad r(x_k + \alpha_k p_k)^T p_k \ge c_2 r_k^T p_k -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10_ - -**Notation:** -x represents solution state vector; f represents objective function; r, g represent residual gradient vectors; p represents search direction vector; \alpha represents line search step length; s_k represents solution increment x_{k+1} - x_k; y_k represents residual increment r_{k+1} - r_k; B_k represents Hessian approximation; H_k represents inverse Hessian approximation operator. - - -## 3. Algorithmic Implementation - -**unconstrained-quasi-newton-driver** -$$ -\begin{algorithmic} -\State $\text{Initialize solution vector } x_0, \text{ initial positive-definite matrix } H_0, \text{ and tolerance } \text{tol}$ -\For{$k = 0, 1, 2, \dots \text{ until } \|r_k\|_2 < \text{tol}$} -\State $\text{Evaluate residual gradient } r_k = \nabla f(x_k)$ -\State $\text{Compute descent search direction } p_k = -H_k r_k$ -\State $\text{Determine step length } \alpha_k > 0 \text{ satisfying Wolfe conditions } f(x_k + \alpha_k p_k) \le f(x_k) + c_1 \alpha_k r_k^T p_k$ -\State $x_{k+1} = x_k + \alpha_k p_k$ -\State $s_k = x_{k+1} - x_k, \quad y_k = r_{k+1} - r_k$ -\State $\text{Update inverse Hessian approximation } H_{k+1} \text{ using } s_k \text{ and } y_k$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10, Algorithm 1; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 6_ - - -## 4. Known Pitfalls - -- **non-convex-hessian-indefiniteness**: In non-convex physical problems (such as phase-field fracture or post-peak softening), the true tangent stiffness Hessian matrix \nabla^2 f(x) becomes indefinite or non-symmetric. Standard Newton updates without line search or positive-definite quasi-Newton scaling diverge or generate non-descent search directions. _(Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 5)_ -- **curvature-condition-violation**: Updating quasi-Newton Hessian approximations when the curvature condition s_k^T y_k \le 0 is violated destroys the positive definiteness of H_{k+1}. Enforcing strong Wolfe line search conditions or skipping updates under negative curvature ensures s_k^T y_k > 0 and preserves descent directions. _(Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.1, p. 10; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2, p. 6)_ - -## References - -- Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf -- Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf -- Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-abaqus-umat-uel.md b/packages/akms/src/akms/_bundled/global_nodes/pf-abaqus-umat-uel.md deleted file mode 100644 index e7ad145..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-abaqus-umat-uel.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -id: pf-abaqus-umat-uel -title: Phase-Field Implementation in Abaqus (UEL/UMAT) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- abaqus -- UEL -- UMAT -- molnar-2017 -- wu-huang-2020 -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-fem-implementation - type: refines - weight: 0.7 -- to: pf-staggered-scheme - type: feeds-into - weight: 0.5 -- to: pf-monolithic-bfgs - type: feeds-into - weight: 0.5 -- to: pf-benchmarks - type: feeds-into - weight: 0.5 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Phase-Field Implementation in Abaqus (UEL/UMAT) - -## Summary - -Comprehensive implementation framework for phase-field fracture and damage models in the commercial finite element suite Abaqus using User Element (UEL), User Material (UMAT), and thermo-mechanical analogy subroutines. The node covers three primary solution architectures: (1) UMAT-Newton-M using built-in thermal degrees of freedom and HETVAL/UMATHT subroutines for weakly coupled or modified Newton schemes, (2) UEL-Staggered using multi-layer user elements with dummy rotational degrees of freedom or global iteration counters to enforce alternate minimization, and (3) UEL-BFGS monolithic quasi-Newton implementations that combine high numerical robustness with 3x-7x computational speedups over staggered solvers. It also details multi-layer element topologies, dummy UMAT post-processing overlays for visualization in Abaqus/CAE, and elasto-plastic extensions combining von Mises or GTN damage criteria with phase-field energy degradation. - -## 1. Core Concept - -Implementation of non-local phase-field damage models in commercial finite element software (Abaqus) requires bridging the gap between built-in solver architectures and the coupled partial differential equations governing mechanical equilibrium and diffusive crack phase-field evolution. Because standard Newton monolithic schemes often fail due to the non-convexity of the total energy functional with respect to simultaneous displacement and damage variations, specialized implementation strategies are required. These include user-defined element (UEL) subroutines implementing the Broyden-Fletcher-Goldfarb-Shanno (BFGS) quasi-Newton algorithm with uncoupled initial block-diagonal stiffness matrices, multi-pass alternate minimization (staggered) solvers using dummy control degrees of freedom (e.g., DOF 6), and thermo-mechanical analogy routines (UMAT/HETVAL) mapping the phase-field variable to temperature and the thermodynamic driving force to internal heat generation. To overcome Abaqus UEL limitations regarding post-processing, a multi-layer element structure is used wherein fictitious Abaqus native elements with near-zero stiffness (dummy UMAT) share nodes with UELs to export solution-dependent state variables (SDVs) for visualization in Abaqus/CAE. - -## 2. Mathematical Formulation - -**mechanical_equilibrium_abaqus** -$$ -\nabla \cdot \boldsymbol{\sigma} + \mathbf{b} = \rho \ddot{\mathbf{u}} \quad \text{with} \quad \boldsymbol{\sigma} = \omega(d) \bar{\boldsymbol{\sigma}}_d + \bar{\boldsymbol{\sigma}}_0 -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method_ - -**phase_field_governing_equation** -$$ -\frac{c_{\alpha}}{b} G_f \alpha'(d) - 2 b c_{\alpha} G_f \Delta d = -\omega'(d) \mathcal{H} + \eta \dot{d} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**history_field_definition** -$$ -\mathcal{H}_{n+1} = \max\left(\mathcal{H}_n, \bar{Y}_{n+1}\right), \quad \bar{Y} = \frac{\bar{\sigma}_{eq}^2}{2 E_0} \quad \text{or} \quad \mathcal{H}_{n+1} = \max\left(\mathcal{H}_n, \psi_0^+ + \psi_0^{pl} - \psi_c\right) -$$ -_Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - -**linearized_monolithic_system** -$$ -\begin{bmatrix} \mathbf{K}_{uu} & \mathbf{K}_{ud} \\ \mathbf{K}_{du} & \mathbf{K}_{dd} \end{bmatrix} \begin{Bmatrix} \delta \mathbf{a} \\ \delta \bar{\mathbf{a}} \end{Bmatrix} = \begin{Bmatrix} \mathbf{r}_u \\ \mathbf{r}_d \end{Bmatrix} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**bfgs_initial_stiffness_and_update** -$$ -\tilde{\mathbf{K}}^{(0)} = \begin{bmatrix} \mathbf{K}_{uu} & \mathbf{0} \\ \mathbf{0} & \mathbf{K}_{dd} \end{bmatrix}, \quad \tilde{\mathbf{K}}_{k+1}^{-1} = \left(\mathbf{I} - \frac{\delta \mathbf{z} \delta \mathbf{g}^T}{\delta \mathbf{z}^T \delta \mathbf{g}}\right) \tilde{\mathbf{K}}_k^{-1} \left(\mathbf{I} - \frac{\delta \mathbf{g} \delta \mathbf{z}^T}{\delta \mathbf{z}^T \delta \mathbf{g}}\right) + \frac{\delta \mathbf{z} \delta \mathbf{z}^T}{\delta \mathbf{z}^T \delta \mathbf{g}} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**thermal_analogy_source_term** -$$ -Q(d) = \frac{c_{\alpha}}{2 b G_f} \omega'(d) \mathcal{H} + \frac{1}{c_{\alpha} b} \alpha'(d) G_f, \quad \text{with conductivity } k=1 -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - -**Notation:** -\mathbf{u}: displacement vector; d: scalar phase-field damage variable (d \in [1]); \boldsymbol{\sigma}: Cauchy stress tensor; \boldsymbol{\epsilon}: small strain tensor; \mathbf{B}: strain-displacement interpolation matrix; \bar{\mathbf{N}}, \bar{\mathbf{B}}: shape function matrix and gradient matrix for damage field; \mathbf{a}: nodal displacement degrees of freedom; \bar{\mathbf{a}}: nodal phase-field degrees of freedom; \mathcal{H}: history variable field; G_f: critical energy release rate; b, l_c: length scale parameter; \omega(d): degradation function; \alpha(d): crack geometric function; \mathbf{r}_u, \mathbf{r}_d: mechanical and phase-field residual vectors; \mathbf{z}: unified nodal solution vector; \text{SDV}: solution-dependent state variables in Abaqus. - - -## 3. Algorithmic Implementation - -**uel-bfgs-monolithic** -$$ -\begin{algorithmic} -\State $Initialize nodal displacement vector \mathbf{a}_0, phase-field vector \bar{\mathbf{a}}_0, combined solution vector \mathbf{z}_0 = \{\mathbf{a}_0, \bar{\mathbf{a}}_0\}^T, and element history field \mathcal{H}_0 = 0.$ -\For{$Loop over load/time increments n = 1, 2, \dots, N_{steps}.$} -\State $Set iteration counter k = 0, initial trial solution \mathbf{z}_{n+1}^{(0)} = \mathbf{z}_n, and compute residual vector \mathbf{g}^{(0)} = [\mathbf{r}_u(\mathbf{z}_{n+1}^{(0)})^T, \mathbf{r}_d(\mathbf{z}_{n+1}^{(0)})^T]^T.$ -\State $Assemble uncoupled block-diagonal initial stiffness matrix \tilde{\mathbf{K}}^{(0)} = \text{diag}(\mathbf{K}_{uu}(\mathbf{z}_{n+1}^{(0)}), \mathbf{K}_{dd}(\mathbf{z}_{n+1}^{(0)})) in UEL subroutine.$ -\While{$Residual norm \|\mathbf{g}^{(k)}\| > \text{tol} \cdot \tilde{q}_{force}.$} -\State $Compute solution correction \delta \mathbf{z} = (\tilde{\mathbf{K}}^{(k)})^{-1} \mathbf{g}^{(k)} using quasi-Newton solver.$ -\State $Update solution vector \mathbf{z}^{(k+1)} = \mathbf{z}^{(k)} + \delta \mathbf{z}.$ -\State $At element Gauss integration points, evaluate strain \boldsymbol{\epsilon}^{(k+1)} = \mathbf{B} \mathbf{a}^{(k+1)}, effective strain energy \bar{Y}^{(k+1)}, and update history field \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \bar{Y}^{(k+1)}).$ -\State $Compute updated residual vector \mathbf{g}^{(k+1)} and change in residual \delta \mathbf{g} = \mathbf{g}^{(k+1)} - \mathbf{g}^{(k)}.$ -\State $Update inverse stiffness matrix \tilde{\mathbf{K}}_{k+1}^{-1} using rank-two BFGS update formula.$ -\State $Increment iteration counter k \leftarrow k + 1.$ -\EndWhile -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**uel-staggered-dummy-dof** -$$ -\begin{algorithmic} -\State $Read global solution counter isw passed from Abaqus solver framework to UEL subroutine.$ -\If{$isw == -1 (Odd iteration: displacement sub-problem).$} -\State $Evaluate element displacement stiffness matrix \mathbf{K}_{uu} = \int_{\Omega} \mathbf{B}^T \boldsymbol{\sigma}_{tan} \mathbf{B} d\Omega and displacement residual \mathbf{r}_u = \mathbf{f}_{ext} - \int_{\Omega} \mathbf{B}^T \boldsymbol{\sigma} d\Omega.$ -\State $Set dummy DOF 6 residual to a large penalty value (10^3) and set damage residuals \mathbf{r}_d = \mathbf{0} to force Abaqus to perform an additional iteration while keeping damage fixed.$ -\Else -\State $Update element history field \mathcal{H} = \max(\mathcal{H}_n, \bar{Y}(\boldsymbol{\epsilon})).$ -\State $Evaluate element damage stiffness matrix \mathbf{K}_{dd} and damage residual vector \mathbf{r}_d.$ -\State $Set displacement residuals \mathbf{r}_u = \mathbf{0} and dummy DOF 6 residual to 0 to solve damage with fixed displacement.$ -\EndIf -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - -**multi-layer-postprocessing-overlay** -$$ -\begin{algorithmic} -\State $Define Layer 1 elements (e.g., U1 or CPS4/C3D8) contributing stiffness to displacement DOFs (1, 2, 3).$ -\State $Define Layer 2 elements (e.g., U2 or phase UEL) sharing identical nodes contributing stiffness to phase-field DOF (11).$ -\State $Define Layer 3 overlaid elements sharing the same node connectivity using standard Abaqus solid elements (CPS4/C3D8) governed by a dummy UMAT with negligible stiffness E_{dummy} = 10^{-10} \text{ MPa}.$ -\State $In Layer 1/Layer 2 subroutines, write integration point state variables (phase field d, equivalent plastic strain \varepsilon_{eq}^{pl}, stresses \boldsymbol{\sigma}, strain energy \psi^+) into a shared COMMON block or solution-dependent state variable array STATEV.$ -\State $In Layer 3 UMAT subroutine, read shared SDV values and assign them to output SDV array for contour plotting in Abaqus/CAE Viewer.$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids based on the shear-modified GTN model_ - - -## 4. Known Pitfalls - -- **monolithic-newton-nonconvexity-divergence**: Standard Newton-Raphson monolithic algorithms in Abaqus frequently fail or diverge during crack initiation and propagation. This occurs because the total energy functional is non-convex with respect to displacement and damage fields simultaneously, causing negative eigenvalues in the coupled tangent matrix and numerical jumps. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method)_ -- **staggered-solver-computational-inefficiency**: While the alternate minimization (staggered) scheme is robust, it converges extremely slowly in critical crack-propagation increments, often requiring over 1,000 iterations per increment and leading to prohibitive CPU runtimes (up to 7x slower than BFGS quasi-Newton monolithic solvers). _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ -- **fictitious-stiffness-volumetric-locking-under-compression**: Applying degraded elastic strain energy or improper strain energy splits under heavy hydrostatic compression can cause non-physical damage evolution or artificial volumetric locking. In compressive/shear fracture, energy splits must preserve compressive stiffness (e.g., spectral or deviatoric/volumetric splits) and use numerical stability parameters k \approx 10^{-8} to avoid zero-stiffness singularities at d=1. _(Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture)_ -- **postprocessing-visualization-limitation-in-uel**: User-defined elements (UEL) in Abaqus do not automatically export internal integration point state variables to Abaqus/CAE visualization databases (.odb). Bypassing this requires adding an overlaid layer of standard dummy elements with near-zero stiffness (dummy UMAT) or using post-processing scripts (e.g., Abaqus2Matlab) to transfer SDVs to nodal fields. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids)_ - -## References - -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Molnar, G., Gravouil, A., Seghir, R., and Réthoré, J. (2020). An open-source Abaqus implementation of the phase-field method to study the effect of plasticity on the instantaneous fracture toughness in dynamic crack propagation. Computer Methods in Applied Mechanics and Engineering, 365, 113004. -- Tao, Z., et al. (2022). Phase-field modeling of 3D fracture in elasto-plastic solids based on the shear-modified GTN model and Abaqus subroutines UEL/UMAT. Engineering Fracture Mechanics, 260, 108196. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Wang, T., Ye, X., Liu, Z., Liu, X., Chu, D., and Zhuang, Z. (2020). A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration. Computational Mechanics, 65(5), 1305-1321. -- Miehe, C., Welschinger, F., and Hofacker, M. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-at1-regularization.md b/packages/akms/src/akms/_bundled/global_nodes/pf-at1-regularization.md deleted file mode 100644 index b651f96..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-at1-regularization.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -id: pf-at1-regularization -title: AT1 Regularization (Linear Crack Density) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- AT1 -- regularization -- elastic-limit -- bound-constraint -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-variational-griffith - type: refines - weight: 0.7 -- to: pf-at2-regularization - type: contradicts - weight: 0.0 -- to: pf-cohesive-zone - type: feeds-into - weight: 0.5 -- to: pf-staggered-scheme - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# AT1 Regularization (Linear Crack Density) - -## Summary - -The AT1 phase-field damage formulation (Pham et al., 2011) employs a linear geometric crack function \alpha(d) = d and quadratic energetic degradation function \omega(d) = (1-d)^2 to model brittle fracture with a distinct finite elastic regime. Unlike the standard AT2 model—which initiates damage immediately upon non-zero strain—AT1 incorporates a strictly positive elastic limit threshold stress \sigma_c = \sqrt{3 E_0 G_f / (8 b)}, below which the material remains purely elastic. The geometric crack density surface functional incorporates a geometric scaling constant c_{\alpha} = 8/3 and a regularization length scale b. Numerical implementation of AT1 requires bound-constrained variational inequality solvers or history-field updates to rigorously enforce damage irreversibility \dot{d} \ge 0 and phase-field boundedness 0 \le d \le 1. - -## 1. Core Concept - -The AT1 model is a regularized gradient-damage approximation of Griffith brittle fracture that introduces a purely linear geometric crack density function \alpha(d) = d. In contrast to AT2 regularization where \alpha(d) = d^2 causes immediate damage nucleation at infinitesimal stress levels, the linear density in AT1 creates a finite dissipation gradient at d=0. This establishes a well-defined elastic domain bounded by a critical threshold stress \sigma_c = \sqrt{3 E_0 G_f / (8 b)}. During loading below \sigma_c, the thermodynamic damage driving force Q(d) remains strictly negative or zero, preventing spurious damage accumulation. Upon reaching \sigma_c, damage initiates and localizes within a finite crack band of width proportional to length scale b. Because the linear crack function yields a non-zero threshold at d=0, numerical algorithms must enforce bound constraints (0 \le d \le 1) and irreversibility (\dot{d} \ge 0) using active-set methods, augmented Lagrangian formulations, or historical maximum driving force fields \mathcal{H}. Within unified phase-field damage theory, AT1 represents the linear geometric limit precursor to cohesive zone formulations. - -## 2. Mathematical Formulation - -**at1_crack_density_functional** -$$ -\Gamma_b(d) = \int_{B} \gamma(d, \nabla d) dV = \int_{B} \frac{1}{c_{\alpha}} \left[ \frac{\alpha(d)}{b} + b |\nabla d|^2 \right] dV = \int_{B} \frac{3}{8} \left[ \frac{d}{b} + b |\nabla d|^2 \right] dV -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**at1_elastic_limit_threshold** -$$ -\sigma_c = \sqrt{\frac{3 E_0 G_f}{8 b}}, \quad \epsilon_c = \frac{\sigma_c}{E_0} = \sqrt{\frac{3 G_f}{8 E_0 b}} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**at1_governing_microforce_equation** -$$ -\nabla \cdot \mathbf{q} + Q(d) \le 0, \quad \mathbf{q} = \frac{2b}{c_{\alpha}} G_f \nabla d = \frac{3}{4} b G_f \nabla d, \quad Q(d) = -\omega'(d) \mathcal{H} - \frac{G_f}{c_{\alpha} b} \alpha'(d) = 2(1-d) \mathcal{H} - \frac{3 G_f}{8 b} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**at1_irreversibility_history_field** -$$ -\mathcal{H}(x, t) = \max_{\tau \in [0, t]} \bar{Y}(x, \tau), \quad \bar{Y} = \frac{\bar{\sigma}_{eq}^2}{2 E_0} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture_ - -**Notation:** -d: scalar damage variable (d \in [1]); \alpha(d): linear crack geometric function (\alpha(d)=d); \omega(d): energetic degradation function (\omega(d)=(1-d)^2); b: regularization length scale parameter; c_{\alpha}: geometric scaling constant (c_{\alpha}=8/3 for AT1); G_f: critical energy release rate (fracture toughness); E_0: Young's modulus; \sigma_c: finite elastic threshold stress; \mathcal{H}: historical strain energy release rate driving field; \mathbf{q}: microforce damage flux; Q(d): damage source driving force. - - -## 3. Algorithmic Implementation - -**at1-staggered-bound-constrained-solver** -$$ -\begin{algorithmic} -\State $Initialize nodal displacement vector \mathbf{a}_0, nodal damage vector \bar{\mathbf{a}}_0 = \mathbf{0}, and history field \mathcal{H}_0 = 0.$ -\For{$Loop over time increments n = 1, 2, \dots, N_{steps}.$} -\State $Set iteration counter k = 0, initial trial displacement \mathbf{a}_{n+1}^{(0)} = \mathbf{a}_n, and initial trial damage \bar{\mathbf{a}}_{n+1}^{(0)} = \bar{\mathbf{a}}_n.$ -\While{$Residual norm \|\mathbf{g}^{(k)}\| > \text{tol}.$} -\State $Solve mechanical displacement sub-problem for \mathbf{a}_{n+1}^{(k+1)} with fixed damage \bar{\mathbf{a}}_{n+1}^{(k)}: \mathbf{K}_{uu}(\bar{\mathbf{a}}_{n+1}^{(k)}) \delta \mathbf{a} = \mathbf{r}_u.$ -\State $Evaluate effective equivalent stress \bar{\sigma}_{eq} at element integration points and update history field: \mathcal{H}_{n+1} = \max\left(\mathcal{H}_n, \frac{\bar{\sigma}_{eq}^2}{2 E_0}\right).$ -\State $Assemble damage stiffness matrix \mathbf{K}_{dd} = \int_B \left[ 2 \mathcal{H}_{n+1} \bar{\mathbf{N}}^T \bar{\mathbf{N}} + \frac{3}{4} b G_f \bar{\mathbf{B}}^T \bar{\mathbf{B}} \right] dV and damage residual \mathbf{r}_d.$ -\State $Solve damage sub-problem for trial increment: \mathbf{K}_{dd} \delta \bar{\mathbf{a}} = \mathbf{r}_d \implies \bar{\mathbf{a}}_{trial} = \bar{\mathbf{a}}_{n+1}^{(k)} + \delta \bar{\mathbf{a}}.$ -\If{$Bound constraints or damage irreversibility are violated (\bar{\mathbf{a}}_{trial} < \bar{\mathbf{a}}_n or \bar{\mathbf{a}}_{trial} > \mathbf{1}).$} -\State $Enforce nodal bound projections: \bar{\mathbf{a}}_{n+1}^{(k+1)} = \max\left(\bar{\mathbf{a}}_n, \min\left(\mathbf{1}, \bar{\mathbf{a}}_{trial}\right)\right).$ -\EndIf -\State $Increment iteration counter k \leftarrow k + 1.$ -\EndWhile -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Amor et al. (2009), Regularized formulation of the variational brittle fracture with unilateral contact_ - - -## 4. Known Pitfalls - -- **at1-spurious-damage-triggering-below-elastic-limit**: In contrast to the AT2 model where damage initiates at zero stress, AT1 relies on a threshold stress \sigma_c = \sqrt{3 E_0 G_f / (8 b)}. If history field \mathcal{H} is computed without subtracting or accounting for the linear dissipation threshold \frac{3 G_f}{8 b}, numerical errors can trigger premature, unphysical damage evolution below the elastic limit. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ -- **at1-mesh-resolution-and-length-scale-sensitivity**: Because the linear geometric crack function \alpha(d)=d produces a sharp damage profile cusp at d=1, the finite element mesh size h inside the localized crack band must be significantly smaller than length scale b (typically h \le b/5). Coarse meshes fail to resolve the crack surface density \Gamma_b(d), leading to severe mesh-bias and overestimation of peak load capacity. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture)_ - -## References - -- Pham, K., Amor, H., Marigo, J.-J., and Maurini, C. (2011). Gradient damage models and their use to approximate brittle fracture. International Journal of Damage Mechanics, 20(4), 618-652. -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Miehe, C., Welschinger, F., and Hofacker, M. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Amor, H., Marigo, J.-J., and Maurini, C. (2009). Regularized formulation of the variational brittle fracture with unilateral contact: Numerical experiments. Journal of the Mechanics and Physics of Solids, 57(8), 1209-1229. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-at2-regularization.md b/packages/akms/src/akms/_bundled/global_nodes/pf-at2-regularization.md deleted file mode 100644 index b7c4e1e..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-at2-regularization.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -id: pf-at2-regularization -title: AT2 Regularization (Ambrosio-Tortorelli, Quadratic) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- AT2 -- regularization -- miehe -- gamma-convergence -status: tentative -confidence: 0.92 -source: hybrid -confidence_floor: 0.7 -edges: -- to: pf-variational-griffith - type: refines - weight: 0.7 -- to: pf-staggered-scheme - type: feeds-into - weight: 0.5 -- to: pf-fem-implementation - type: feeds-into - weight: 0.5 -- to: pf-at1-regularization - type: contradicts - weight: 0.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# AT2 Regularization (Ambrosio-Tortorelli, Quadratic) - -## Summary -AT2 is the standard quadratic regularization of variational fracture due -to Ambrosio-Tortorelli (1990) and popularized for FE by Miehe et al. -(2010). The crack surface density is gamma_l = (1/2*ell)*d^2 + (ell/2)*|grad d|^2, -the elastic energy is degraded by g(d)=(1-d)^2, and the resulting governing -PDE is linear in d when the source psi+ is fixed. Mesh refinement requires -h <= ell/2. AT2 has no elastic limit — any non-zero stress nucleates damage — -which limits its quantitative use but makes it numerically robust. - - -## 1. Core Concept -AT2 takes the form discovered by Ambrosio-Tortorelli (1990) as a -Gamma-convergent approximation to the Mumford-Shah image-segmentation -functional and adapted by Bourdin-Francfort-Marigo (2000) and Miehe- -Welschinger-Hofacker (2010) for fracture mechanics. - -The regularized energy reads - E_l(u, d) = integral_Omega [(1-d)^2 + k] psi(eps(u)) dV - + Gc * integral_Omega [(1/(2*ell)) * d^2 + (ell/2)|grad d|^2] dV -where k is a small residual stiffness (~1e-6) preventing system -ill-conditioning at d=1, and ell is the regularization length. - -Stationarity in d (assuming d unconstrained) yields a linear screening -equation: - Gc * (d/ell - ell * laplace(d)) = 2*(1-d) * psi+(eps) -often written using the history variable kappa = max(psi+) for -irreversibility. The constitutive update for u uses degraded stress -sigma = (1-d)^2 * dpsi/deps. - -AT2 has the closed-form 1D solution under uniaxial homogeneous load -predicting d -> 1 at sigma -> 0+, i.e., infinitesimal stress nucleates -damage. Hence "no elastic limit" — sigma_c -> 0 as ell -> 0. AT2 is -best for brittle fracture with crack propagation, less so for nucleation -thresholds. - - -## 2. Mathematical Formulation -The AT2 regularization uses quadratic crack surface density and quadratic -degradation, leading to a linear elliptic PDE for the phase field with -elasticity-driven source. - - -**at2-energy:** - -$$ -\mathcal{E}_\ell(\mathbf{u}, d) \;=\; \int_\Omega [(1-d)^2 + k]\,\psi^+(\boldsymbol{\varepsilon}) \,dV \;+\; G_c \int_\Omega \!\left[\frac{d^2}{2\ell} + \frac{\ell}{2}|\nabla d|^2\right] dV -$$ - -where k approx 1e-6: residual stiffness; psi+ = active (tensile) part of strain energy - -**phase-field-pde:** - -$$ -\frac{G_c}{\ell}\, d \;-\; G_c \ell \, \nabla^2 d \;=\; 2(1-d)\,\mathcal{H} -$$ - -where H = max_{tau<=t} psi+ (history variable enforcing irreversibility per Miehe 2010) - -**stress-update:** - -$$ -\boldsymbol{\sigma} \;=\; [(1-d)^2 + k] \, \frac{\partial \psi^+}{\partial \boldsymbol{\varepsilon}} \;+\; \frac{\partial \psi^-}{\partial \boldsymbol{\varepsilon}} -$$ - -where psi+/psi- split (spectral or vol-dev) prevents damage in compression - -**irreversibility-history:** - -$$ -\mathcal{H}(\mathbf{x}, t) \;=\; \max_{\tau \in [0, t]} \psi^+(\boldsymbol{\varepsilon}(\mathbf{x}, \tau)) -$$ - -where history-variable formulation per Miehe 2010 — replaces unilateral constraint - -**elastic-limit:** - -$$ -\sigma_c \;=\; \frac{9}{16}\sqrt{\frac{2 E G_c}{3\ell}} \cdot 0 \;\equiv\; 0 \quad \text{(AT2 has no elastic limit)} -$$ - -where closed-form 1D analysis: damage initiates at any sigma > 0 — AT2 cannot capture finite strength - -**mesh-requirement:** - -$$ -h \;\le\; \ell/2 \quad \text{(typical guideline for resolving diffuse crack)} -$$ - -where h = element size; coarser meshes overestimate Gc by approximately (1 + h/(2*c_w*ell)) where c_w = 1/2 for AT2 - -**Notation:** - -- $d$ — phase field in [0,1] (Miehe notation) -- $phi$ — synonym for d (Bourdin notation) -- $k$ — residual stiffness ~ 1e-6 -- $psi+, psi-$ — tensile/compressive split of strain energy -- $H$ — history field enforcing irreversibility -- $ell$ — regularization length -- $c_w$ — 1/2 for AT2 (normalization in Gamma-limit) - - -## 3. Algorithmic Implementation -**Algorithm: at2-staggered-step** - -$$ -\begin{algorithmic} -\State $$ -\State $$ -\State $$ -\State $$ -\State $$ -\State $$ -\State $$ -\State $$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Two passes per outer iteration: first a sparse-Helmholtz solve for d -(coefficient depends on H stored at GP), then standard elasticity -assembly with (1-d)^2 modulating the GP-level tangent. Use -ti.linalg.SparseSolver for both. - - - -## 4. Known Pitfalls -**no-elastic-limit:** AT2 cannot represent a finite tensile strength sigma_c. As soon as -psi+ > 0 the phase field starts evolving. For problems requiring a -strength criterion (e.g., quasi-brittle materials with peak load), -use AT1 or PF-CZM instead. - - -**damage-in-compression:** Without an energy split, AT2 produces unphysical damage under -hydrostatic compression. Always use spectral, vol-dev, or no-tension -decomposition of psi. - - -**mesh-bias:** Cracks aligned with mesh edges propagate slightly cheaper than -diagonal cracks. Use isotropic h-AMR or anisotropic remeshing where -d > 0.1 to mitigate. - - -**small-k-conditioning:** The residual stiffness k must be small enough not to overestimate -cracked stiffness but large enough not to ill-condition the linear -system. Typical k = 1e-6 to 1e-9 of E. - - -**history-vs-bound-enforcement:** Miehe history variable H is mathematically equivalent to enforcing -the bound d_dot >= 0 only when no compressive unloading occurs. For -cyclic loading, use active-set bound enforcement (more expensive -but more accurate). - - -## 5. References -- Miehe, C., Welschinger, F., Hofacker, M. (2010). Thermodynamically consistent phase-field models of fracture: variational principles and multi-field FE implementations. IJNME 83:1273-1311. -- Ambrosio, L., Tortorelli, V. M. (1990). Approximation of functionals depending on jumps by elliptic functionals via Gamma-convergence. CPAM 43:999-1036. -- Bourdin, B., Francfort, G. A., Marigo, J.-J. (2000). Numerical experiments in revisited brittle fracture. JMPS 48:797-826. -- Bourdin, B., Francfort, G. A., Marigo, J.-J. (2008). The variational approach to fracture. Springer. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-benchmarks.md b/packages/akms/src/akms/_bundled/global_nodes/pf-benchmarks.md deleted file mode 100644 index 84eaaf5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-benchmarks.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -id: pf-benchmarks -title: Phase-Field Fracture Benchmarks -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- benchmarks -- SENT -- kalthoff-winkler -- sneddon -- validation -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-fem-implementation - type: refines - weight: 0.7 -- to: pf-at2-regularization - type: feeds-into - weight: 0.5 -- to: pf-dynamic-brittle - type: feeds-into - weight: 0.5 -- to: pf-staggered-scheme - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Phase-Field Fracture Benchmarks - -## Summary - -Standardized computational benchmarks for validating phase-field fracture and damage formulations across quasi-static, dynamic, brittle, and ductile failure regimes. Key benchmark suites include: (1) Single-Edge Notched Tension (SENT) and Shear (SENS) tests verifying Mode I straight crack propagation and mixed-mode curved cracking under strain energy decompositions, (2) Kalthoff-Winkler plate impact tests capturing the dynamic transition from brittle tensile fracture at ~70° propagation angle under low impact velocity (v_0 ≈ 20 m/s) to ductile adiabatic shear banding (~-8° angle) at high impact velocity (v_0 ≥ 30 m/s), (3) Symmetric and Asymmetric Three-Point Bending (TPB) tests validating crack trajectory curvature around geometric obstacles, and (4) L-shaped panel tests evaluating mixed-mode crack initiation at re-entrant corners. - -## 1. Core Concept - -Validation and verification of phase-field fracture models rely on canonical benchmark problems that test fundamental physical and numerical capabilities: crack nucleation, strain-energy decomposition robustness, mixed-mode path selection, and dynamic failure mode transitions. Quasi-static benchmarks such as SENT and SENS establish basic accuracy in predicting crack initiation loads and path deflection under tensile versus shear loading. Dynamic impact benchmarks, exemplified by the Kalthoff-Winkler test, evaluate the model's ability to capture wave-reflection-driven fracture and the rate-dependent transition between brittle tensile cracking (driven by tensile elastic strain energy) and thermo-plastic shear localization (driven by plastic work and thermal softening). Numerical accuracy across these benchmarks requires resolving the regularized crack localization band (h ≤ b/5) and avoiding spurious stress singularities at point-load or support boundaries. - -## 2. Mathematical Formulation - -**sent_sens_governing_energy** -$$ -E(\mathbf{u}, d) = \int_{\Omega} \left[ g(d) \psi_0^+(\boldsymbol{\epsilon}) + \psi_0^-(\boldsymbol{\epsilon}) \right] d\Omega + \int_{B} G_f \gamma(d, \nabla d) d\Omega -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture_ - -**kalthoff_winkler_dynamic_energy_balance** -$$ -\rho \ddot{\mathbf{u}} = \nabla \cdot \boldsymbol{\sigma}, \quad \boldsymbol{\sigma} = g(d) \frac{\partial \psi_0^+}{\partial \boldsymbol{\epsilon}} + \frac{\partial \psi_0^-}{\partial \boldsymbol{\epsilon}}, \quad 2 w_c \left[ d - l^2 \Delta d \right] = 2(1-d) \mathcal{H} -$$ -_Source: Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration_ - -**kalthoff_winkler_transition_velocity** -$$ -v_{impact} < v_{crit} \implies \theta_{crack} \approx 70^\circ \quad (\text{brittle Mode I}), \quad v_{impact} \ge v_{crit} \implies \theta_{shear} \approx -8^\circ \quad (\text{ductile shear band}) -$$ -_Source: Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II; McAuliffe and Waisman (2016), A coupled phase field shear band model for ductile-brittle transition_ - -**l_shaped_panel_mixed_mode_crack** -$$ -\mathcal{H}(\mathbf{x}, t) = \max_{\tau \in [0,t]} \bar{Y}(\boldsymbol{\epsilon}(\mathbf{x}, \tau)), \quad \mathbf{K}_{dd} \mathbf{d} = \mathbf{r}_d -$$ -_Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Zhang et al. (2022), Assessment of four strain energy decomposition methods_ - -**Notation:** -\mathbf{u}: displacement vector; d: scalar phase-field damage variable (d \in [1]); \boldsymbol{\sigma}: degraded stress tensor; \psi_0^+, \psi_0^-: tensile and compressive strain energy densities; G_f: fracture toughness; b, l: regularization length scale parameter; \rho: material density; v_0, v_{impact}: projectile velocity; \theta_{crack}: crack deflection angle; \mathcal{H}: history variable field preserving energy maximum. - - -## 3. Algorithmic Implementation - -**sent-sens-benchmark-procedure** -$$ -\begin{algorithmic} -\State $Set up 1 mm \times 1 mm square domain with a 0.5 mm horizontal notch at y=0.5 mm and refined mesh h \le b/5 along the expected crack path.$ -\For{$Loop over load increments n = 1, 2, \dots, N_{steps}.$} -\State $For SENT (Mode I): apply incremental vertical displacement \Delta u_y > 0 on top boundary with bottom fixed (u_x = u_y = 0).$ -\State $For SENS (Mode II/Mixed-Mode): apply incremental horizontal shear displacement \Delta u_x > 0, u_y = 0 on top boundary with bottom fixed.$ -\State $Solve coupled mechanical equilibrium and phase-field evolution equations using staggered or BFGS quasi-Newton solver.$ -\State $Update integration point strain energy \psi_0^+ and history field \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \psi_0^+).$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Zhang et al. (2022), Assessment of four strain energy decomposition methods_ - -**kalthoff-winkler-impact-benchmark** -$$ -\begin{algorithmic} -\State $Define double pre-notched plate specimen (100 mm \times 200 mm, notch length 50 mm, notch spacing 50 mm) with density \rho and elastic/plastic properties.$ -\State $Apply symmetric velocity profile v_0 across the edge segment between the two notch tips over rise time t_0 = 0.1 \ \mu\text{s}.$ -\If{$Impact velocity v_0 = 20 \text{ m/s} (Low loading rate).$} -\State $Observe tensile stress wave reflection at notch tip generating Mode I stress field; brittle crack initiates and propagates at \approx 70^\circ angle.$ -\ElsIf{$Impact velocity v_0 \ge 30 \text{ m/s} (High loading rate).$} -\State $Observe intense plastic strain accumulation and thermal/softening localization at notch tip; adiabatic shear band initiates and propagates horizontally at \approx -8^\circ.$ -\EndIf -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II; McAuliffe and Waisman (2016), A coupled phase field shear band model for ductile-brittle transition_ - - -## 4. Known Pitfalls - -- **sens-crack-path-dependency-on-energy-split**: In Single-Edge Notched Shear (SENS) tests, the predicted crack propagation trajectory is highly sensitive to the strain energy decomposition method (e.g., spectral vs. deviatoric split). Unsplit energy functions cause non-physical crack propagation under compressive stress zones. _(Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods for phase field fracture; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture)_ -- **kalthoff-winkler-mesh-bias-and-velocity-toughening**: In dynamic impact benchmarks such as Kalthoff-Winkler, coarse meshes (h > b/2) around the notch tip introduce numerical wave dispersion and artificially elevate the critical transition velocity for shear banding. Furthermore, neglecting dynamic inertia terms in J-integral evaluations distorts the calculation of the instantaneous stress intensity factor K_{ID}. _(Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II)_ -- **tpb-lshaped-spurious-damage-at-point-load-supports**: In Three-Point Bending (TPB) and L-shaped panel benchmarks, applying point loads or rigid displacement constraints directly to single nodes creates non-physical stress singularities. This causes artificial localized damage nucleation at support points rather than at the notch or re-entrant corner unless distributed contact/traction boundary conditions are applied. _(Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods for phase field fracture; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ - -## References - -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Miehe, C., Hofacker, M., Schänzel, L.-M., and Aldakheel, F. (2015). Phase field modeling of fracture in multi-physics problems. Part II. Coupled brittle-to-ductile failure criteria and crack propagation in thermo-elastic-plastic solids. Computer Methods in Applied Mechanics and Engineering, 294, 486-522. -- McAuliffe, C., and Waisman, H. (2016). A coupled phase field shear band model for ductile–brittle transition in notched plate impacts. Computer Methods in Applied Mechanics and Engineering, 305, 173-195. -- Zhang, Z., et al. (2022). Assessment of four strain energy decomposition methods for phase field fracture models. Materials Theory, 6, 6. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Molnar, G., Gravouil, A., Seghir, R., and Réthoré, J. (2020). An open-source Abaqus implementation of the phase-field method to study the effect of plasticity on the instantaneous fracture toughness in dynamic crack propagation. Computer Methods in Applied Mechanics and Engineering, 365, 113004. -- Wang, T., Ye, X., Liu, Z., Liu, X., Chu, D., and Zhuang, Z. (2020). A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration. Computational Mechanics, 65(5), 1305-1321. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-cohesive-zone.md b/packages/akms/src/akms/_bundled/global_nodes/pf-cohesive-zone.md deleted file mode 100644 index 80d8c22..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-cohesive-zone.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: pf-cohesive-zone -title: Cohesive Phase-Field Model (PF-CZM, Wu Unified Theory) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- cohesive -- PF-CZM -- wu -- length-insensitive -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-variational-griffith - type: refines - weight: 0.7 -- to: pf-at1-regularization - type: refines - weight: 0.7 -- to: pf-at2-regularization - type: refines - weight: 0.7 -- to: pf-staggered-scheme - type: feeds-into - weight: 0.5 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Cohesive Phase-Field Model (PF-CZM, Wu Unified Theory) - -## Summary - -The phase-field regularized cohesive zone model (PF-CZM), developed within Wu's unified phase-field damage theory, bridges gradient-damage mechanics and classical cohesive zone models (CZM) for quasi-brittle and cohesive fracture. PF-CZM employs a specific geometric crack function \alpha(d) = 2d - d^2 (with scaling constant c_{\alpha} = \pi) and a rational energetic degradation function \omega(d) = (1-d)^p / [(1-d)^p + a_1 d P(d)] to strictly satisfy physical traction-separation laws (such as linear, exponential, or Cornelissen softening). A hallmark feature of PF-CZM is that the global load-displacement response and peak structural load capacity are length-scale insensitive with respect to the regularization parameter b, provided b \le l_{ch}/3 (where l_{ch} = E_0 G_f / f_t^2 is Irwin's characteristic length). Furthermore, PF-CZM naturally recovers Barenblatt-type cohesive fracture profiles without requiring pre-defined crack paths or mesh-alignment constraints. - -## 1. Core Concept - -Classical phase-field brittle fracture models (such as AT1 and AT2) exhibit strong dependence of structural peak load on the internal length scale parameter b, which acts purely as a numerical regularization parameter or artificial strength governor. Wu's unified phase-field damage theory resolves this limitation by constructing a phase-field regularized cohesive zone model (PF-CZM) where material tensile strength f_t, fracture energy G_f, Young's modulus E_0, and cohesive traction-separation laws are independently and consistently prescribed. By adopting a parabolic geometric crack function \alpha(d) = 2d - d^2 and a parameterized rational energetic degradation function \omega(d), the damage driving force is calibrated against Irwin's characteristic length l_{ch} = E_0 G_f / f_t^2 via scaling parameter a_1 = (4/\pi)(l_{ch}/b). As a result, the macroscopic structural response becomes insensitive to length scale b (for b \le l_{ch}/3), eliminating artificial mesh-bias and permitting coarse-mesh approximations outside the localization band. Within a variational and coupled continuum framework, PF-CZM rigorously reproduces classical Barenblatt and Dugdale cohesive crack profiles across arbitrary 2D and 3D geometries. - -## 2. Mathematical Formulation - -**pf_czm_geometric_crack_function** -$$ -\alpha(d) = 2d - d^2, \quad c_{\alpha} = 4 \int_0^1 \sqrt{\alpha(\beta)} d\beta = \pi -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**pf_czm_energetic_degradation_function** -$$ -\omega(d) = \frac{(1-d)^p}{(1-d)^p + a_1 d P(d)}, \quad P(d) = 1 + a_2 d + a_3 d^2 -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**pf_czm_softening_parameter_calibration** -$$ -\text{Linear: } p=2, a_2=-\frac{1}{2}, a_3=0; \quad \text{Exponential: } p=2.5, a_2=2^{5/3}-3, a_3=0; \quad \text{Cornelissen: } p=2, a_2=1.3868, a_3=0.9106 -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**pf_czm_governing_microforce_balance** -$$ -\nabla \cdot \mathbf{q} + Q(d) \le 0, \quad \mathbf{q} = \frac{2b}{\pi} G_f \nabla d, \quad Q(d) = -\omega'(d) \mathcal{H} - \frac{G_f}{\pi b} \alpha'(d) -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**pf_czm_length_scale_insensitivity_bound** -$$ -b \le \frac{1}{3} l_{ch} = \frac{1}{3} \frac{E_0 G_f}{f_t^2} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**Notation:** -d: scalar damage variable (d \in); \omega(d): rational energetic degradation function; \alpha(d): parabolic geometric crack function (\alpha(d)=2d-d^2); b: regularization length scale parameter; l_{ch}: Irwin's characteristic material length (l_{ch} = E_0 G_f / f_t^2); f_t: uniaxial tensile strength; G_f: critical fracture energy; E_0: Young's modulus; \mathcal{H}: history field of maximum effective strain energy release rate; \mathbf{q}: microforce flux vector; Q(d): thermodynamic damage driving force source. - - -## 3. Algorithmic Implementation - -**pf-czm-bfgs-monolithic-solver** -$$ -\begin{algorithmic} -\State $Initialize displacement degrees of freedom \mathbf{a}_0, damage degrees of freedom \bar{\mathbf{a}}_0, combined solution vector \mathbf{z}_0 = \{\mathbf{a}_0, \bar{\mathbf{a}}_0\}^T, and initial history field \mathcal{H}_0 = \frac{f_t^2}{2 E_0}.$ -\For{$Loop over load/displacement increments n = 1, 2, \dots, N_{steps}.$} -\State $Set iteration index k = 0, initial solution guess \mathbf{z}_{n+1}^{(0)} = \mathbf{z}_n, and compute residual vector \mathbf{g}^{(0)} = [\mathbf{r}_u(\mathbf{z}_{n+1}^{(0)})^T, \mathbf{r}_d(\mathbf{z}_{n+1}^{(0)})^T]^T.$ -\State $Set uncoupled initial block-diagonal inverse stiffness matrix \tilde{\mathbf{K}}^{(0)-1} = \text{diag}(\mathbf{K}_{uu}^{-1}, \mathbf{K}_{dd}^{-1}).$ -\While{$Residual norm \|\mathbf{g}^{(k)}\| > \text{tol}.$} -\State $Compute solution update step: \delta \mathbf{z} = \tilde{\mathbf{K}}^{(k)-1} \mathbf{g}^{(k)}.$ -\State $Update solution vector: \mathbf{z}^{(k+1)} = \mathbf{z}^{(k)} + \delta \mathbf{z}.$ -\State $At Gauss integration points, evaluate effective equivalent stress \bar{\sigma}_{eq}^{(k+1)} and update history variable field: \mathcal{H}_{n+1} = \max\left(\mathcal{H}_n, \frac{\bar{\sigma}_{eq}^{(k+1)2}}{2 E_0}\right).$ -\State $Evaluate updated residuals \mathbf{g}^{(k+1)} and residual increment \delta \mathbf{g} = \mathbf{g}^{(k+1)} - \mathbf{g}^{(k)}.$ -\State $Update inverse stiffness matrix \tilde{\mathbf{K}}_{k+1}^{-1} using rank-two BFGS update formula: \tilde{\mathbf{K}}_{k+1}^{-1} = \left(\mathbf{I} - \frac{\delta \mathbf{z} \delta \mathbf{g}^T}{\delta \mathbf{z}^T \delta \mathbf{g}}\right) \tilde{\mathbf{K}}_k^{-1} \left(\mathbf{I} - \frac{\delta \mathbf{g} \delta \mathbf{z}^T}{\delta \mathbf{z}^T \delta \mathbf{g}}\right) + \frac{\delta \mathbf{z} \delta \mathbf{z}^T}{\delta \mathbf{z}^T \delta \mathbf{g}}.$ -\State $Increment iteration counter k \leftarrow k + 1.$ -\EndWhile -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - - -## 4. Known Pitfalls - -- **pf-czm-length-scale-upper-bound-violation**: If the regularization length scale b exceeds the critical material upper bound b > \frac{1}{3} l_{ch} = \frac{1}{3} \frac{E_0 G_f}{f_t^2}, the positive-definiteness condition -\partial Q / \partial d \ge 0 of the damage sub-problem is violated upon damage initiation. This causes loss of length-scale insensitivity and premature loss of numerical stability. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ -- **pf-czm-localization-band-mesh-resolution**: Although PF-CZM structural load-displacement responses are insensitive to length scale parameter b, the finite element mesh size h within the active damage localization band B must still be sufficiently fine (typically h \le b/5) to resolve the localized damage gradient \nabla d, otherwise numerical locking or mesh alignment bias occurs. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ - -## References - -- Wu, J.-Y. (2017). A unified phase-field theory for the mechanics of damage and quasi-brittle failure. Journal of the Mechanics and Physics of Solids, 103, 72-99. -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Alessi, R., Marigo, J.-J., Maurini, C., and Vidoli, S. (2018). Coupling damage and plasticity for a phase-field regularisation of brittle, cohesive and ductile fracture: One-dimensional examples. International Journal of Mechanical Sciences, 149, 559-576. -- Zhang, H., Pei, X.-Y., Peng, H., and Wu, J.-Y. (2021). Phase-field modeling of spontaneous shear bands in collapsing thick-walled cylinders. Engineering Fracture Mechanics, 249, 107706. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-ductile-mixed-mode.md b/packages/akms/src/akms/_bundled/global_nodes/pf-ductile-mixed-mode.md deleted file mode 100644 index 5cd7964..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-ductile-mixed-mode.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -id: pf-ductile-mixed-mode -title: Mixed-Mode & Shear-Driven Ductile Phase-Field -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- mixed-mode -- shear -- cup-cone -- slant-fracture -- talamini -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-ductile-plasticity-coupling - type: refines - weight: 0.7 -- to: pf-spectral-split - type: requires - weight: 1.0 -- to: pf-porous-ductile - type: feeds-into - weight: 0.5 -- to: damage-bai-wierzbicki - type: refines - weight: 0.7 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Mixed-Mode & Shear-Driven Ductile Phase-Field - -## Summary - -Formulation and implementation of mixed-mode and shear-driven ductile phase-field fracture models across multiaxial loading conditions. To accurately capture fracture initiation and localization under low, negative, or mixed stress triaxialities—where standard tensile energy degradation fails—the framework incorporates stress-state dependency characterized by stress triaxiality \eta = -p/q and the normalized Lode angle parameter \theta. Key formulation strategies include: (1) integrating phenomenological fracture loci (e.g., Modified Mohr-Coulomb / Bai-Wierzbicki criteria) into the damage driving threshold to construct a loading-history indicator D(\epsilon^p) for threshold-gated damage initiation, (2) double phase-field formulations with distinct phase variables d_I (tensile/spall) and d_{II} (shear/localization) driven by volumetric tensile energy \psi_{vol}^+ and plastic/elastic deviatoric work \psi_{dev}, and (3) hybrid coupled degradation functions combining scalar phase-field damage with void volume fraction f and shear damage D_s (e.g., shear-modified GTN phase-field models). - -## 1. Core Concept - -Modeling shear-dominated and mixed-mode ductile fracture within a regularized phase-field continuum requires extending classical brittle energy-split concepts (such as spectral or volumetric-deviatoric splits) to account for plastic strain accumulation, hydrostatic pressure, and Lode-angle sensitivity. In purely tensile or high-triaxiality regimes, microvoid growth dominates and crack initiation can be captured using degraded plastic strain energy. However, under shear or compression-shear loading (low or negative triaxiality), void growth is suppressed, and failure proceeds via intense shear band localization. Standard phase-field models falsely predict zero damage or numerical locking in compression unless deviatoric plastic work \int \boldsymbol{s} : d\boldsymbol{\epsilon}^p and stress-state dependent threshold functions \epsilon_f(\eta, \theta, \dot{\epsilon}^p) drive phase-field evolution. Modern frameworks resolve this using either: (i) stress-state-dependent damage indicators D(\epsilon^p) based on the Modified Mohr-Coulomb (MMC) criterion, where phase-field evolution is triggered only when D=1, or (ii) double phase-field formulations that maintain separate phase fields d_I and d_{II} with distinct fracture energies G_f^I, G_f^{II} and driving forces \mathcal{H}_I, \mathcal{H}_{II}, coupled through a unified combined damage scalar d = 1 - (1-d_I)(1-d_{II}). - -## 2. Mathematical Formulation - -**mmc_fracture_strain_triaxiality_lode** -$$ -\epsilon_f(\eta, \theta, \dot{\epsilon}^p) = b \left[ A c_2 \left( c_3 + \frac{\sqrt{3}}{2-\sqrt{3}}(1-c_3)\left[\sec\left(\frac{\theta \pi}{6}\right)-1\right] \right) \left( 1 + c_2 \frac{\sqrt{3}}{3} \cos\left(\frac{\theta \pi}{6}\right) + c_1 \left[\eta + \frac{1}{3}\sin\left(\frac{\theta \pi}{6}\right)\right] \right) \right]^{-1/n} -$$ -_Source: Li et al. (2025), Phase field fracture in elastoplastic solids: a stress-state, strain-rate, and orientation dependent model_ - -**loading_history_damage_indicator** -$$ -D(\epsilon^p) = \int_0^{\epsilon^p} \frac{d\epsilon^p}{\epsilon_f(\eta, \theta, \dot{\epsilon}^p)}, \quad \text{with crack initiation triggered at } D=1 -$$ -_Source: Li et al. (2025), Phase field fracture in elastoplastic solids; Bai and Wierzbicki (2008), A new model of metal plasticity and fracture_ - -**double_phase_field_coupled_governing_equations** -$$ -\eta_I \dot{d}_I = 2 b_I^2 \Delta d_I - (1-d_{II}) \omega_I'(d) \mathcal{H}_I - \alpha_I'(d_I), \quad \eta_{II} \dot{d}_{II} = 2 b_{II}^2 \Delta d_{II} - (1-d_I) \omega_{II}'(d) \mathcal{H}_{II} - \alpha_{II}'(d_{II}) -$$ -_Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals_ - -**shear_modified_gtn_degradation_coupling** -$$ -g(d, D_s, f) = (1-d)^{(a_1 + a_2 D_s + a_3 f)}, \quad \dot{D}_s = \psi(\theta, T^*) \frac{n D_s^{(n-1)/n}}{\epsilon_f^s} \dot{\epsilon}_q^m -$$ -_Source: Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids based on the shear-modified GTN model_ - -**Notation:** -d, d_I, d_{II}: scalar phase-field damage variables; \eta, T^*: stress triaxiality (\eta = -p/q); \theta: normalized Lode angle parameter; \epsilon^p, \epsilon_q^m: equivalent plastic strain; \epsilon_f: fracture strain; D: damage indicator; D_s: shear damage; f: void volume fraction; \psi_{vol}^+, \psi_{vol}^-: positive and negative volumetric strain energy densities; \psi_{dev}: deviatoric strain energy density (including plastic work); \mathcal{H}_I, \mathcal{H}_{II}: historical damage driving energy fields; G_f^I, G_f^{II}: critical fracture energies for tensile and shear modes; b_I, b_{II}, l_c: regularization length scale parameters. - - -## 3. Algorithmic Implementation - -**explicit-dynamics-stress-state-ductile-pf** -$$ -\begin{algorithmic} -\State $Initialize displacement \mathbf{u}_0, velocity \dot{\mathbf{u}}_0, plastic strain \epsilon_0^p, damage indicator D_0 = 0, and phase field d_0 = 0.$ -\For{$Loop over explicit time steps n = 0, 1, 2, \dots, N_{steps}.$} -\State $Compute trial stress state \tilde{\boldsymbol{\sigma}}_{n+1}^{trial} using corotational hypoelastic-plastic predictor.$ -\State $Evaluate current stress triaxiality \eta_{n+1} = -p/q and Lode angle parameter \theta_{n+1}.$ -\State $Calculate failure strain \epsilon_f(\eta_{n+1}, \theta_{n+1}, \dot{\epsilon}^p) from MMC criterion and update damage indicator: D_{n+1} = D_n + \Delta \epsilon^p / \epsilon_f.$ -\If{$D_{n+1} \ge 1 (Damage initiation threshold reached).$} -\State $Compute history driving field \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \bar{Y}_{n+1}) incorporating deviatoric plastic work and elastic strain energy.$ -\State $Update phase field d_{n+1} explicitly by solving: \varpi \dot{d} = (1-d)\mathcal{H}_{n+1} - (d - l_c^2 \Delta d).$ -\EndIf -\State $Degrade Cauchy stress tensor: \boldsymbol{\sigma}_{n+1} = (1 - d_{n+1})^2 \tilde{\boldsymbol{\sigma}}_{n+1} and update nodal accelerations \ddot{\mathbf{u}}_{n+1} = \mathbf{M}^{-1} (\mathbf{F}_{ext} - \mathbf{F}_{int}).$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Li et al. (2025), Phase field fracture in elastoplastic solids: a stress-state, strain-rate, and orientation dependent model_ - -**coupled-double-phase-field-solver** -$$ -\begin{algorithmic} -\State $Initialize nodal displacements \mathbf{u}_0, tensile phase field d_{I,0} = 0, shear phase field d_{II,0} = 0, and combined damage d_0 = 0.$ -\For{$Loop over time increments n = 0, 1, \dots, N_{steps}.$} -\State $Decompose undamaged strain energy into tensile volumetric \psi_{vol}^+, compressive volumetric \psi_{vol}^-, and plastic/elastic deviatoric \psi_{dev}.$ -\State $Update tensile driving force \mathcal{H}_I = \frac{2 b_I}{G_f^I} \max_{\tau \le t} \psi_{vol}^+ and shear driving force \mathcal{H}_{II} = \frac{2 b_{II}}{G_f^{II}} \max_{\tau \le t} \psi_{dev}.$ -\State $Solve coupled phase-field sub-problem for d_{I,n+1}: \eta_I \dot{d}_I - 2 b_I^2 \Delta d_I = -(1-d_{II,n}) \omega_I'(d_n) \mathcal{H}_I - \alpha_I'(d_{I,n}).$ -\State $Solve coupled phase-field sub-problem for d_{II,n+1}: \eta_{II} \dot{d}_{II} - 2 b_{II}^2 \Delta d_{II} = -(1-d_{I,n+1}) \omega_{II}'(d_n) \mathcal{H}_{II} - \alpha_{II}'(d_{II,n}).$ -\State $Compute updated combined damage: d_{n+1} = 1 - (1-d_{I,n+1})(1-d_{II,n+1}).$ -\State $Evaluate degraded Cauchy stress: \boldsymbol{\sigma}_{n+1} = -\omega_I(d) H(-p) p \mathbf{I} - H(p) p \mathbf{I} + \omega_{II}(d) \mathbf{s}.$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals_ - - -## 4. Known Pitfalls - -- **shear-driven-fracture-locking-under-compression**: In shear-dominated or mixed-mode ductile fracture under heavy hydrostatic compression, standard unsplit or purely volumetric energy degradation methods cause non-physical volumetric locking and artificial damage suppression. Properly decoupling tensile volumetric and deviatoric strain energy components—and degrading deviatoric and tensile volumetric stresses while keeping compressive pressure undegraded—is required to accurately predict shear band and mixed-mode crack trajectories. _(Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Zhang et al. (2022), Assessment of four strain energy decomposition methods)_ -- **neglecting-lode-angle-in-low-triaxiality-shear-fracture**: Relying solely on stress triaxiality \eta = -p/q to drive ductile fracture fails in low or negative triaxiality regimes (e.g., simple shear or compression-shear). Omitting the Lode angle parameter \theta leads to severe underestimation of shear damage initiation and incorrect predictions of mixed-mode crack deflection angles. _(Source: Li et al. (2025), Phase field fracture in elastoplastic solids; Bai and Wierzbicki (2008), A new model of metal plasticity and fracture)_ -- **unphysical-early-damage-accumulation-prior-to-plastic-yield**: Using standard quadratic degradation functions g(d) = (1-d)^2 without an explicit plastic work or strain-state threshold (such as MMC D=1 or critical plastic strain \alpha_c) causes the phase field d to evolve prematurely during early elastic deformation, artificially lowering the macroscopic yield stress. _(Source: Borden et al. (2016), A phase-field formulation for fracture in ductile materials; Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II; Li et al. (2025), Phase field fracture in elastoplastic solids)_ - -## References - -- Li, C., Liu, J., Dong, L., Wu, C., Steven, G., Li, Q., and Fang, J. (2025). Phase field fracture in elastoplastic solids: a stress-state, strain-rate, and orientation dependent model in explicit dynamics and its applications to additively manufactured metals. Journal of the Mechanics and Physics of Solids, 197, 105978. -- Zhang, H., Peng, H., Pei, X.-Y., Wu, J.-Y., Li, P., Tang, T.-G., Cai, L.-C., Li, Y., and Liu, H. (2023). Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals. Journal of the Mechanics and Physics of Solids, 172, 105186. -- Tao, Z., Li, X., Tao, S., and Chen, Z. (2022). Phase-field modeling of 3D fracture in elasto-plastic solids based on the modified GTN theory and Abaqus subroutines UEL/UMAT. Engineering Fracture Mechanics, 260, 108196. -- Borden, M. J., Hughes, T. J. R., Landis, C. M., Anvari, A., and Lee, I. J. (2016). A phase-field formulation for fracture in ductile materials: Finite deformation balance law derivation, plastic degradation, and stress triaxiality effects. Computer Methods in Applied Mechanics and Engineering, 312, 130-166. -- Miehe, C., Hofacker, M., Schänzel, L.-M., and Aldakheel, F. (2015). Phase field modeling of fracture in multi-physics problems. Part II. Coupled brittle-to-ductile failure criteria and crack propagation in thermo-elastic-plastic solids. Computer Methods in Applied Mechanics and Engineering, 294, 486-522. -- Zhang, H., Pei, X.-Y., Peng, H., and Wu, J.-Y. (2021). Phase-field modeling of spontaneous shear bands in collapsing thick-walled cylinders. Engineering Fracture Mechanics, 249, 107706. -- Zhang, Z., et al. (2022). Assessment of four strain energy decomposition methods for phase field fracture models. Materials Theory, 6, 6. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-ductile-plasticity-coupling.md b/packages/akms/src/akms/_bundled/global_nodes/pf-ductile-plasticity-coupling.md deleted file mode 100644 index ea61022..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-ductile-plasticity-coupling.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -id: pf-ductile-plasticity-coupling -title: Coupled Plasticity–Phase-Field Fracture (Borden, Miehe) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- plasticity -- ductile -- borden-2016 -- plastic-work-driving -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-variational-griffith - type: refines - weight: 0.7 -- to: pf-spectral-split - type: requires - weight: 1.0 -- to: plasticity-isotropic-hardening - type: requires - weight: 1.0 -- to: pf-ductile-mixed-mode - type: feeds-into - weight: 0.5 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Coupled Plasticity–Phase-Field Fracture (Borden, Miehe) - -## Summary - -Formulation, energy splitting, and return-mapping algorithms for coupled elastoplasticity and diffusive phase-field fracture in ductile materials. Based on foundational continuum mechanics frameworks by Borden et al. (2016) and Miehe et al. (2015), the node details the energetic and microforce balance governing coupled plastic dissipation and damage evolution. Key aspects include: (1) free-energy potential decomposition incorporating degraded hyperelastic/elastic strain energy and plastic work, (2) yield surface degradation functions g_p(c) that induce plastic softening and eliminate non-physical elastic deformation after crack initiation, (3) plastic work thresholds \langle W_p - W_0 \rangle or accumulated plastic strain driving fields \mathcal{H}_p that prevent premature damage nucleation prior to macroscopic yielding, and (4) J2 flow theory return-mapping algorithms integrating plastic yield surface degradation with objective configuration updates. - -## 1. Core Concept - -Coupling continuum plasticity with phase-field fracture requires unifying two dissipative mechanisms: irreversible dislocation slip (plastic flow) and diffusive crack surface evolution (damage). In classical brittle phase-field formulations, crack propagation is driven purely by elastic strain energy release rate. In ductile metals, however, plastic deformation absorbs significant energy, producing localized plastic work and strain-rate-dependent thermal softening before macroscopic crack initiation occurs. To capture this physics without predicting artificial damage prior to yielding, the free energy functional is split into elastic and plastic contributions. The elastic strain energy (often partitioned via volumetric-deviatoric or principal stretch splits rather than strict spectral splits) drives damage evolution alongside an accumulated plastic work density W_p or plastic threshold field \mathcal{H}_p. Crucially, to model post-initiation softening and maintain thermodynamic consistency, the plastic yield function f(\boldsymbol{\tau}, \alpha) = \|\mathbf{s}\| - g_p(c)\sqrt{2/3}k(\alpha) incorporates a yield surface degradation function g_p(c). This degrades material flow strength as damage c \to 1, eliminating spurious residual stresses in fully broken material zones. - -## 2. Mathematical Formulation - -**free_energy_density_ductile_pf** -$$ -\rho_0 \psi(\mathbf{C}, \mathbf{C}^p, \alpha, c, \nabla_X c) = g(c) W^+(\mathbf{C}, \mathbf{C}^p) + W^-(\mathbf{C}, \mathbf{C}^p) + g_p(c) W_p(\alpha) + \frac{G_c}{2 \ell_0} \left[ \frac{(1-c)^2}{2} + \ell_0^2 |\nabla_X c|^2 \right] -$$ -_Source: Borden et al. (2016), A phase-field formulation for fracture in ductile materials; Borden et al. (2017), Corrigendum_ - -**microforce_phase_field_governing_equation** -$$ -2 \ell_0 \frac{G_c}{c_0} \left[ \beta_e \frac{dg}{dc} \mathcal{H}_e + \beta_p \frac{dg_p}{dc} \langle W_p - W_0 \rangle \right] + c - 4 \ell_0^2 \Delta_X c = 1 -$$ -_Source: Borden et al. (2016), A phase-field formulation for fracture in ductile materials; Borden et al. (2017), Corrigendum_ - -**degraded_j2_yield_function** -$$ -f(\boldsymbol{\tau}, \alpha, c) = \|\mathbf{s}\| - g_p(c) \sqrt{\frac{2}{3}} k(\alpha) \le 0 -$$ -_Source: Borden et al. (2016), A phase-field formulation for fracture in ductile materials; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method_ - -**plastic_work_driving_history_field** -$$ -\mathcal{H}_{n+1} = \max\left( \mathcal{H}_n, \psi_0^+ + \psi_0^{pl} - \psi_c \right), \quad \psi_0^{pl} = \int_0^t \boldsymbol{\sigma} : d\boldsymbol{\epsilon}^p -$$ -_Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture_ - -**alessi_coupled_1d_yield_surface** -$$ -f_p(\sigma, c) = |\sigma| - \sigma_P(c) \le 0, \quad \sigma_P(c) = (1-c)^s \sigma_p -$$ -_Source: Alessi et al. (2018), Coupling damage and plasticity for a phase-field regularisation of brittle, cohesive and ductile fracture_ - -**Notation:** -c: scalar phase-field damage variable (c \in [1]); \mathbf{C}, \mathbf{C}^p: total and plastic right Cauchy-Green deformation tensors; \boldsymbol{\tau}: Kirchhoff stress tensor; \mathbf{s}: deviatoric Kirchhoff stress tensor; \boldsymbol{\sigma}: Cauchy stress tensor; \boldsymbol{\epsilon}^p: plastic strain tensor; \alpha: equivalent plastic strain / isotropic hardening variable; k(\alpha): isotropic yield stress function; g(c), g_p(c): elastic and plastic yield surface degradation functions; W^+, W^-: positive (tensile) and negative (compressive) strain energy density components; W_p: plastic work density; W_0, \psi_c: threshold plastic/elastic energy density; G_c: fracture toughness; \ell_0: regularization length scale parameter; \mathcal{H}_e, \mathcal{H}: energy history fields. - - -## 3. Algorithmic Implementation - -**j2-plasticity-return-mapping-with-phase-field-degradation** -$$ -\begin{algorithmic} -\State $Given state at time t_n: deformation gradient \mathbf{F}_n, plastic intermediate metric \bar{\mathbf{b}}_n^e, isotropic hardening variable \alpha_n, damage c_n, and incremental displacement \Delta \mathbf{u}_n.$ -\State $Update deformation gradient \mathbf{F}_{n+1} = \mathbf{f}_{n+1} \mathbf{F}_n with relative deformation gradient \mathbf{f}_{n+1} = \mathbf{I} + \nabla \mathbf{u}_n.$ -\State $Compute trial elastic predictor configuration: \bar{\mathbf{b}}_{n+1}^{e, trial} = \bar{\mathbf{f}}_{n+1} \bar{\mathbf{b}}_n^e \bar{\mathbf{f}}_{n+1}^T where \bar{\mathbf{f}}_{n+1} = \det(\mathbf{f}_{n+1})^{-1/3} \mathbf{f}_{n+1}.$ -\State $Evaluate trial deviatoric Kirchhoff stress: \mathbf{s}_{n+1}^{trial} = g(c_n) \mu \text{dev}[\bar{\mathbf{b}}_{n+1}^{e, trial}].$ -\State $Evaluate trial yield function: f_{n+1}^{trial} = \|\mathbf{s}_{n+1}^{trial}\| - g_p(c_n) \sqrt{\frac{2}{3}} k(\alpha_n).$ -\If{$f_{n+1}^{trial} \le 0 (Elastic step).$} -\State $Accept trial state: \mathbf{s}_{n+1} = \mathbf{s}_{n+1}^{trial}, \alpha_{n+1} = \alpha_n, \bar{\mathbf{b}}_{n+1}^e = \bar{\mathbf{b}}_{n+1}^{e, trial}, and \Delta \gamma = 0.$ -\Else -\State $Solve non-linear scalar plastic consistency equation for algorithmic plastic multiplier \Delta \gamma: \hat{f}(\Delta \gamma) = \|\mathbf{s}_{n+1}^{trial}\| - g_p(c_n) \sqrt{\frac{2}{3}} k\left(\alpha_n + \sqrt{\frac{2}{3}} \Delta \gamma\right) - 2 \bar{\mu} \Delta \gamma = 0 where \bar{\mu} = g(c_n) \mu \frac{1}{3} \text{tr}[\bar{\mathbf{b}}_{n+1}^{e, trial}].$ -\State $Update deviatoric stress and hardening parameter: \mathbf{s}_{n+1} = \mathbf{s}_{n+1}^{trial} - 2 \bar{\mu} \Delta \gamma \frac{\mathbf{s}_{n+1}^{trial}}{\|\mathbf{s}_{n+1}^{trial}\|}, \alpha_{n+1} = \alpha_n + \sqrt{\frac{2}{3}} \Delta \gamma.$ -\State $Update intermediate elastic metric maintaining unit determinant: \text{dev}[\bar{\mathbf{b}}_{n+1}^e] = \frac{\mathbf{s}_{n+1}}{g(c_n) \mu}, solve \det\left(\text{dev}[\bar{\mathbf{b}}_{n+1}^e] + \bar{I}_{n+1}^e \mathbf{I}\right) = 1 for \bar{I}_{n+1}^e, set \bar{\mathbf{b}}_{n+1}^e = \text{dev}[\bar{\mathbf{b}}_{n+1}^e] + \bar{I}_{n+1}^e \mathbf{I}.$ -\EndIf -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borden et al. (2016), A phase-field formulation for fracture in ductile materials; Borden et al. (2017), Corrigendum_ - - -## 4. Known Pitfalls - -- **spurious-elastic-energy-after-crack-initiation-without-yield-degradation**: If the plastic yield surface is not degraded simultaneously with elastic stiffness (i.e. omitting g_p(c)), material inside fully broken crack zones (c \to 1) continues to yield at high flow stress. This generates non-physical elastic strains, artificial residual stresses, and incorrect strain energy calculations across fully fractured elements. _(Source: Borden et al. (2016), A phase-field formulation for fracture in ductile materials; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method)_ -- **premature-damage-nucleation-prior-to-plastic-yield**: Using a pure elastic driving force or standard quadratic degradation g(c) = (1-c)^2 without a plastic threshold W_0 or \psi_c causes phase field c to evolve during early elastic deformation. This prematurely degrades initial elastic stiffness and artificially depresses the macroscopic yield strength. _(Source: Borden et al. (2016), A phase-field formulation for fracture in ductile materials; Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II)_ -- **volumetric-compression-locking-under-plastic-shear**: Failing to split or treat compressive pressure independently during plastic shear deformation causes non-physical damage growth under hydrostatic compression. Models must employ volumetric-deviatoric or principal stretch splits to prevent compressive energy from driving crack phase-field evolution. _(Source: Borden et al. (2016), A phase-field formulation for fracture in ductile materials; McAuliffe and Waisman (2015), A unified model for metal failure capturing shear banding and fracture)_ - -## References - -- Borden, M. J., Hughes, T. J. R., Landis, C. M., Anvari, A., and Lee, I. J. (2016). A phase-field formulation for fracture in ductile materials: Finite deformation balance law derivation, plastic degradation, and stress triaxiality effects. Computer Methods in Applied Mechanics and Engineering, 312, 130-166. -- Borden, M. J., Hughes, T. J. R., Landis, C. M., Anvari, A., and Lee, I. J. (2017). Corrigendum to "A phase-field formulation for fracture in ductile materials: Finite deformation balance law derivation, plastic degradation, and stress triaxiality effects". Computer Methods in Applied Mechanics and Engineering, 324, 712-713. -- Miehe, C., Hofacker, M., Schänzel, L.-M., and Aldakheel, F. (2015). Phase field modeling of fracture in multi-physics problems. Part II. Coupled brittle-to-ductile failure criteria and crack propagation in thermo-elastic-plastic solids. Computer Methods in Applied Mechanics and Engineering, 294, 486-522. -- Alessi, R., Marigo, J.-J., Maurini, C., and Vidoli, S. (2018). Coupling damage and plasticity for a phase-field regularisation of brittle, cohesive and ductile fracture: One-dimensional examples. International Journal of Mechanical Sciences, 149, 559-576. -- Molnar, G., Gravouil, A., Seghir, R., and Réthoré, J. (2020). An open-source Abaqus implementation of the phase-field method to study the effect of plasticity on the instantaneous fracture toughness in dynamic crack propagation. Computer Methods in Applied Mechanics and Engineering, 365, 113004. -- Dittmann, M., Aldakheel, F., Schulte, J., Schmidt, F., Krüger, M., Wriggers, P., and Hesch, C. (2020). Phase-field modeling of porous-ductile fracture in non-linear thermo-elasto-plastic solids. Computer Methods in Applied Mechanics and Engineering, 361, 112730. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-dynamic-brittle.md b/packages/akms/src/akms/_bundled/global_nodes/pf-dynamic-brittle.md deleted file mode 100644 index a8db9e5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-dynamic-brittle.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: pf-dynamic-brittle -title: 'Dynamic Phase-Field: Brittle Crack Propagation & Branching' -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- dynamic -- brittle -- branching -- borden-2012 -- yoffe -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-at2-regularization - type: refines - weight: 0.7 -- to: pf-explicit-time-integration - type: feeds-into - weight: 0.5 -- to: pf-spectral-split - type: requires - weight: 1.0 -- to: pf-dynamic-shear-bands - type: refines - weight: 0.7 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Dynamic Phase-Field: Brittle Crack Propagation & Branching - -## Summary - -Formulation, governing equations, and numerical implementation of dynamic phase-field models for brittle crack propagation, velocity acceleration, and spontaneous crack branching. The continuum framework couples elastodynamics with a diffusive crack interface field d, governed by macro-momentum balance \rho \ddot{\mathbf{u}} = \nabla \cdot \boldsymbol{\sigma} + \mathbf{b} and microforce balance for the phase field. Crack initiation, propagation, and branching emerge naturally as thermodynamic energy dissipation processes driven by the historical maximum strain energy release rate \mathcal{H}, without requiring extrinsic tracking or ad hoc branching criteria. Physical resolution of dynamic branching instabilities requires resolving the length scale l_c with fine spatial discretization (h \le l_c/2) and explicit or implicit time integration algorithms. - -## 1. Core Concept - -Dynamic fracture in brittle materials involves complex wave-structure interactions, crack tip acceleration toward Rayleigh wave speed c_R, and spontaneous crack branching under dynamic loading rates. Linear elastic fracture mechanics (LEFM) requires ad hoc criteria to predict when and where a crack will branch or arrest. The dynamic phase-field approach replaces sharp crack interfaces with a regularized crack functional governed by internal length scale l_c, incorporating kinetic energy density \frac{1}{2}\rho |\dot{\mathbf{u}}|^2 into the continuum balance principles. As a crack accelerates under dynamic impact or tensile traction, kinetic and strain energy accumulate around the crack tip; when the local thermodynamic driving force significantly exceeds critical fracture toughness g_c, single-crack propagation becomes unstable, triggering spontaneous crack tip splitting and branching. The phase-field formulation naturally captures stress wave reflections off boundaries, surface roughening, and velocity-toughening effects without explicit interface tracking. - -## 2. Mathematical Formulation - -**dynamic_brittle_momentum_balance** -$$ -\rho \ddot{\mathbf{u}} = \nabla \cdot \boldsymbol{\sigma} + \mathbf{b}, \quad \boldsymbol{\sigma} = g(d) \frac{\partial \psi_0^+}{\partial \boldsymbol{\epsilon}} + \frac{\partial \psi_0^-}{\partial \boldsymbol{\epsilon}} -$$ -_Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method_ - -**dynamic_phase_field_governing_equation** -$$ -g_c l_c \Delta d - \frac{g_c}{l_c} d + 2(1-d) \mathcal{H} = \eta \dot{d} -$$ -_Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Zhang et al. (2022), Assessment of four strain energy decomposition methods_ - -**dynamic_history_variable_field** -$$ -\mathcal{H}(\mathbf{x}, t) = \max_{\tau \in [0, t]} \psi_0^+(\mathbf{x}, \tau) -$$ -_Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture_ - -**rayleigh_wave_speed_limit** -$$ -c_R \approx 0.926 \sqrt{\frac{\mu}{\rho}} \quad \text{for Poisson's ratio } \nu = 0.25 -$$ -_Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding_ - -**Notation:** -\mathbf{u}: displacement vector; \ddot{\mathbf{u}}: acceleration vector; d: scalar phase-field damage variable (d \in [1]); \boldsymbol{\sigma}: degraded Cauchy stress tensor; \psi_0^+, \psi_0^-: tensile and compressive strain energy densities; g_c: critical fracture energy density; l_c: regularization length scale parameter; \rho: material mass density; c_R: Rayleigh wave velocity; \mathcal{H}: history variable field; \eta: viscous damping parameter. - - -## 3. Algorithmic Implementation - -**explicit-dynamic-phase-field-staggered-step** -$$ -\begin{algorithmic} -\State $Initialize nodal displacement \mathbf{u}_0, velocity \dot{\mathbf{u}}_0, acceleration \ddot{\mathbf{u}}_0, damage d_0 = 0, and history field \mathcal{H}_0 = 0.$ -\For{$Loop over time increments n = 0, 1, 2, \dots, N_{steps} with time step size \Delta t.$} -\State $Update nodal displacements using explicit time integration: \mathbf{u}_{n+1} = \mathbf{u}_n + \Delta t \dot{\mathbf{u}}_n + \frac{\Delta t^2}{2} \ddot{\mathbf{u}}_n.$ -\State $At element integration points, compute updated strain \boldsymbol{\epsilon}_{n+1} = \nabla^{sym} \mathbf{u}_{n+1} and positive strain energy density \psi_{0, n+1}^+.$ -\State $Update history driving field: \mathcal{H}_{n+1} = \max\left(\mathcal{H}_n, \psi_{0, n+1}^+\right).$ -\State $Solve uncoupled phase-field equation for d_{n+1}: \left( \frac{g_c}{l_c} + 2 \mathcal{H}_{n+1} + \frac{\eta}{\Delta t} \right) d_{n+1} - g_c l_c \Delta d_{n+1} = 2 \mathcal{H}_{n+1} + \frac{\eta}{\Delta t} d_n.$ -\State $Compute degraded Cauchy stress \boldsymbol{\sigma}_{n+1} = [(1-d_{n+1})^2 + k] \frac{\partial \psi_0^+}{\partial \boldsymbol{\epsilon}} + \frac{\partial \psi_0^-}{\partial \boldsymbol{\epsilon}} and assemble internal force vector \mathbf{F}_{int, n+1}.$ -\State $Compute updated accelerations \ddot{\mathbf{u}}_{n+1} = \mathbf{M}^{-1} (\mathbf{F}_{ext, n+1} - \mathbf{F}_{int, n+1}) and velocities \dot{\mathbf{u}}_{n+1} = \dot{\mathbf{u}}_n + \frac{\Delta t}{2} (\ddot{\mathbf{u}}_n + \ddot{\mathbf{u}}_{n+1}).$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method_ - - -## 4. Known Pitfalls - -- **spurious-branching-from-coarse-mesh-dispersion**: In dynamic fracture simulations, using element size h > l_c/2 causes high-frequency numerical wave dispersion and spurious stress reflections. This distorts the local energy release rate at accelerating crack tips, causing non-physical premature crack branching or mesh-aligned branching trajectories. _(Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture)_ -- **critical-time-step-instability-in-explicit-dynamics**: Explicit time integration for dynamic phase-field fracture requires satisfying the Courant-Friedrichs-Lewy (CFL) stability condition \Delta t \le h / c_p, where c_p is the dilatational wave speed. Extremely fine meshes required to resolve l_c severely reduce \Delta t (often \Delta t \sim 10^{-8} \text{ s} - 10^{-9} \text{ s}), leading to high computational costs. _(Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture; Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding)_ - -## References - -- Wang, T., Ye, X., Liu, Z., Liu, X., Chu, D., and Zhuang, Z. (2020). A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration. Computational Mechanics, 65(5), 1305-1321. -- Molnar, G., Gravouil, A., Seghir, R., and Réthoré, J. (2020). An open-source Abaqus implementation of the phase-field method to study the effect of plasticity on the instantaneous fracture toughness in dynamic crack propagation. Computer Methods in Applied Mechanics and Engineering, 365, 113004. -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Miehe, C., Hofacker, M., Schänzel, L.-M., and Aldakheel, F. (2015). Phase field modeling of fracture in multi-physics problems. Part II. Coupled brittle-to-ductile failure criteria and crack propagation in thermo-elastic-plastic solids. Computer Methods in Applied Mechanics and Engineering, 294, 486-522. -- Zhang, Z., et al. (2022). Assessment of four strain energy decomposition methods for phase field fracture models. Materials Theory, 6, 6. -- Zhang, H., et al. (2023). Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals. Journal of the Mechanics and Physics of Solids, 172, 105186. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-dynamic-shear-bands.md b/packages/akms/src/akms/_bundled/global_nodes/pf-dynamic-shear-bands.md deleted file mode 100644 index c6390d5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-dynamic-shear-bands.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: pf-dynamic-shear-bands -title: Phase-Field for Adiabatic Shear Bands (ASB) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- ASB -- viscoplasticity -- mcauliffe -- zhang-2023 -- high-rate -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-thermomechanical - type: refines - weight: 0.7 -- to: pf-dynamic-brittle - type: refines - weight: 0.7 -- to: thermal-coupled-mechanics - type: requires - weight: 1.0 -- to: plasticity-johnson-cook - type: requires - weight: 1.0 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Phase-Field for Adiabatic Shear Bands (ASB) - -## Summary - -Phase-field formulations for adiabatic shear banding (ASB) and high-strain-rate thermo-plastic localization in dynamic ductile failure. Under impact loading, dynamic collapse, or high-rate penetration, intense plastic working generates thermal softening that localizes into narrow shear bands preceding macroscopic fracture. The continuum framework couples elastodynamics, non-linear viscoplasticity (e.g., Johnson-Cook flow rule), thermal heat diffusion with Taylor-Quinney plastic work conversion, and diffusive phase-field damage evolution. Key modeling features include: (1) inelastic work driving forces P^+ = \int \chi \bar{\tau} \dot{\gamma}^p dt that channel plastic dissipation into phase-field degradation, (2) rational energetic degradation functions \omega(d) capturing three-stage plastic flow stress evolution, and (3) double phase-field formulations (d_I for tensile spall, d_{II} for shear banding) driven by deviatoric and volumetric strain energy splits. - -## 1. Core Concept - -Adiabatic shear banding (ASB) is a catastrophic thermomechanical instability occurring in metals subjected to dynamic impact and high strain rates (> 10^3 s^-1). The instability arises from a competition between strain/strain-rate hardening and thermal softening caused by converted plastic work. Standard local continuum models suffer from severe mesh sensitivity and ill-posedness upon the onset of softening. The phase-field approach regularizes ASBs by introducing an internal length scale b_s or l_0 that defines the physical band width and maintains well-posed governing equations. To model the transition from shear localization to fracture, phase-field formulations incorporate inelastic plastic work P^+ or deviatoric strain energy \psi_{dev} into the damage driving force. In complex dynamic environments (such as collapsing thick-walled cylinders or explosive expanding shells), coupled double phase-field models manage distinct damage variables d_I (tensile spalling) and d_{II} (shear localization), capturing multi-crack interactions, band intersections, counterchecks, and deflection angles without ad hoc nucleation criteria. - -## 2. Mathematical Formulation - -**mcauliffe_thermo_viscoplastic_asb_system** -$$ -\rho_0 \ddot{u}_i = \tau_{ij,j}, \quad \rho_0 \bar{c} \dot{T} = \kappa J T_{,jj} + \chi \bar{\tau} g(\bar{\sigma}, T, \bar{\gamma}^p), \quad \frac{G_c}{4 l_0} c - l_0 G_c \Delta c = (1-c) \left[ W^+ + P^+ \right] -$$ -_Source: McAuliffe and Waisman (2015), A unified model for metal failure capturing shear banding and fracture; McAuliffe and Waisman (2016), A coupled phase field shear band model_ - -**zhang_rational_degradation_three_stage_softening** -$$ -\omega(d) = \frac{(1-d)^2}{(1-d)^2 + a_1 d \left(1 - \frac{1}{2}d\right)}, \quad \sigma_y(d) = \omega(d) \left( A + B (\epsilon^p)^k \right) \left( 1 + C \ln \frac{\dot{\epsilon}^p}{\dot{\epsilon}_0} \right) -$$ -_Source: Zhang et al. (2021a), Phase-field modeling of spontaneous shear bands in collapsing thick-walled cylinders_ - -**double_phase_field_spall_asb_coupled_system** -$$ -\eta_I \dot{d}_I = 2 b_I^2 \Delta d_I - (1-d_{II}) \omega_I'(d) \mathcal{H}_I - \alpha_I'(d_I), \quad \eta_{II} \dot{d}_{II} = 2 b_{II}^2 \Delta d_{II} - (1-d_I) \omega_{II}'(d) \mathcal{H}_{II} - \alpha_{II}'(d_{II}) -$$ -_Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals_ - -**asb_stress_tensor_volumetric_deviatoric_split** -$$ -\boldsymbol{\sigma} = -H(-p) p \mathbf{I} - H(p) \omega_t(d) p \mathbf{I} + \omega_s(d) \mathbf{s} -$$ -_Source: Zhang et al. (2021a), Phase-field modeling of spontaneous shear bands; Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding_ - -**Notation:** -c, d, d_I, d_{II}: scalar phase-field damage variables; \mathbf{u}: displacement vector; \boldsymbol{\tau}: Kirchhoff stress tensor; \boldsymbol{\sigma}: Cauchy stress tensor; \mathbf{s}: deviatoric stress tensor; p: hydrostatic pressure; T: absolute temperature; \chi: Taylor-Quinney inelastic heat conversion factor; \bar{\gamma}^p, \epsilon^p: equivalent plastic strain; W^+: positive elastic strain energy density; P^+: accumulated plastic work driving energy; \psi_{dev}: deviatoric strain energy density; \omega(d), \omega_s(d), \omega_t(d): energetic degradation functions; b_s, b_I, b_{II}, l_0: phase-field length scale parameters. - - -## 3. Algorithmic Implementation - -**coupled-thermomechanical-asb-phase-field-solver** -$$ -\begin{algorithmic} -\State $Initialize displacement \mathbf{u}_0, velocity \dot{\mathbf{u}}_0, temperature T_0, equivalent plastic strain \bar{\gamma}_0^p, accumulated inelastic work P_0^+ = 0, and phase field c_0 = 0.$ -\For{$Loop over time steps n = 0, 1, 2, \dots, N_{steps} with increment \Delta t.$} -\State $Solve elastodynamic momentum equation for displacement \mathbf{u}_{n+1} and trial Kirchhoff stress \boldsymbol{\tau}_{n+1}^{trial}.$ -\State $Perform plastic return-mapping using temperature-dependent Johnson-Cook flow stress \phi(T_n, \bar{\gamma}_n^p, \dot{\bar{\gamma}}^p) to find updated stress \boldsymbol{\tau}_{n+1} and plastic strain rate \dot{\bar{\gamma}}_{n+1}^p.$ -\State $Evaluate Taylor-Quinney thermal source \dot{Q}_{thermal} = \chi \bar{\tau}_{n+1} \dot{\bar{\gamma}}_{n+1}^p and solve heat conduction equation for updated temperature T_{n+1}.$ -\State $Update accumulated inelastic work driving force: P_{n+1}^+ = P_n^+ + \Delta t \cdot \chi \bar{\tau}_{n+1} \dot{\bar{\gamma}}_{n+1}^p.$ -\State $Evaluate elastic strain energy W_{n+1}^+ and assemble phase-field residual vector and stiffness matrix incorporating total driving force (W_{n+1}^+ + P_{n+1}^+).$ -\State $Solve phase-field microforce balance equation for c_{n+1}: \left( \frac{G_c}{4 l_0} + W_{n+1}^+ + P_{n+1}^+ \right) c_{n+1} - l_0 G_c \Delta c_{n+1} = W_{n+1}^+ + P_{n+1}^+.$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: McAuliffe and Waisman (2015), A unified model for metal failure capturing shear banding and fracture; McAuliffe and Waisman (2016), A coupled phase field shear band model_ - - -## 4. Known Pitfalls - -- **mesh-resolution-insufficiency-for-shear-bandwidth**: The phase-field length scale parameter b_s or l_0 determines the physical width of the localized adiabatic shear band (typically 10 \mu\text{m} to 100 \mu\text{m}). If the finite element size h exceeds b_s / 2, numerical wave dispersion distorts shear localization, producing artificially wide bands (> 200 \mu\text{m}) or inaccurate predictions of spontaneous band spacing. _(Source: Zhang et al. (2021a), Phase-field modeling of spontaneous shear bands in collapsing thick-walled cylinders; McAuliffe and Waisman (2016), A coupled phase field shear band model)_ -- **neglecting-inelastic-work-or-thermal-softening-driving-forces**: Using pure elastic strain energy release rate W^+ to drive the phase field in high-strain-rate impact failure causes complete failure of the model to predict shear banding. Because elastic strain energy remains small relative to plastic work during high-rate plastic deformation, omitting accumulated plastic work P^+ or deviatoric work \psi_{dev} prevents damage localization. _(Source: McAuliffe and Waisman (2015), A unified model for metal failure capturing shear banding and fracture; McAuliffe and Waisman (2016), A coupled phase field shear band model)_ -- **unphysical-hydrostatic-pressure-degradation-in-compression**: In dynamic compression problems (e.g. collapsing thick-walled cylinders), degrading total stress isotropic components causes non-physical volumetric collapse under high hydrostatic pressure. To maintain physical validity, compressive pressure must remain strictly undegraded while deviatoric and tensile stresses are degraded by \omega_s(d). _(Source: Zhang et al. (2021a), Phase-field modeling of spontaneous shear bands; Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding)_ - -## References - -- McAuliffe, C., and Waisman, H. (2015). A unified model for metal failure capturing shear banding and fracture. International Journal of Plasticity, 65, 131-151. -- McAuliffe, C., and Waisman, H. (2016). A coupled phase field shear band model for ductile–brittle transition in notched plate impacts. Computer Methods in Applied Mechanics and Engineering, 305, 173-195. -- Zhang, H., Pei, X.-Y., Peng, H., and Wu, J.-Y. (2021a). Phase-field modeling of spontaneous shear bands in collapsing thick-walled cylinders. Engineering Fracture Mechanics, 249, 107706. -- Zhang, H., Peng, H., Pei, X.-Y., Wu, J.-Y., Li, P., Tang, T.-G., Cai, L.-C., Li, Y., and Liu, H. (2023). Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals. Journal of the Mechanics and Physics of Solids, 172, 105186. -- Miehe, C., Hofacker, M., Schänzel, L.-M., and Aldakheel, F. (2015). Phase field modeling of fracture in multi-physics problems. Part II. Coupled brittle-to-ductile failure criteria and crack propagation in thermo-elastic-plastic solids. Computer Methods in Applied Mechanics and Engineering, 294, 486-522. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-energy-split-comparison.md b/packages/akms/src/akms/_bundled/global_nodes/pf-energy-split-comparison.md deleted file mode 100644 index d319bae..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-energy-split-comparison.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: pf-energy-split-comparison -title: Comparison of Strain Energy Decompositions -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- energy-split -- comparison -- no-tension -- star-convex -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-spectral-split - type: refines - weight: 0.7 -- to: pf-voldev-split - type: refines - weight: 0.7 -- to: pf-at2-regularization - type: feeds-into - weight: 0.5 -- to: pf-fem-implementation - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Comparison of Strain Energy Decompositions - -## Summary - -Comparative analysis of strain energy decomposition methods in phase-field fracture modeling, evaluating four canonical formulations: Strain Volumetric-Deviatoric (StrainDe / Amor et al., 2009), Strain Spectral (StrainSp / Miehe et al., 2010), Stress Spectral (StressSp / Zhang et al., 2020), and Stress Volumetric-Deviatoric (StressDe / Zhang et al., 2022), alongside Rankine no-tension criteria (Wu and Huang, 2020). All four energy splits perform identically in pure Mode I tensile loading. However, under pure compression, mixed-mode, or shear loading, their behaviors diverge significantly: volumetric-deviatoric splits accurately capture shear band localization but accumulate unphysical damage under pure hydrostatic compression because deviatoric strain energy is fully degraded. Spectral splits correctly suppress crack initiation under compressive stress states. Computational efficiency differences reported across literature (3x-7x speedup) stem from the choice of global solver (BFGS quasi-Newton monolithic vs. staggered alternate minimization), not the local energy split. - -## 1. Core Concept - -In regularized phase-field fracture mechanics, strain energy decomposition separates the total elastic strain energy density \psi_0(\boldsymbol{\epsilon}) into a crack-driving tensile component \psi^+ (degraded by (1-d)^2) and a non-driving compressive component \psi^- (undegraded). This split models physical unilateral crack-closure contact and prevents artificial cracking in purely compressive domains. Comparative benchmark studies (Zhang et al., 2022) categorize decompositions into strain-based and stress-based splits: (1) Volumetric-Deviatoric splits (Amor et al., 2009; Zhang et al., 2022) partition energy based on trace and deviatoric tensors; while excellent for shear localization, they allow pure shear or compression-shear states to generate damage unless modified. (2) Spectral splits (Miehe et al., 2010) project positive principal strain or stress components using Macaulay brackets \langle \cdot \rangle_\pm, preventing damage under compressive pressure and providing superior accuracy in mixed-mode failure (e.g. SENS, L-shaped panel). Rankine no-tension models (Wu and Huang, 2020) drive damage using maximum principal effective stress \bar{\sigma}_{eq} = \langle \bar{\sigma}_1 \rangle_+. Contrary to prior misconceptions, spectral splits do not cause 3-5x computational slowdowns; overall runtime is governed by monolithic vs. staggered FE solution algorithms. - -## 2. Mathematical Formulation - -**strain_volumetric_deviatoric_split** -$$ -\psi^+(\boldsymbol{\epsilon}) = \frac{1}{2} K_n \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+^2 + \mu \left( \boldsymbol{\epsilon}_{dev} : \boldsymbol{\epsilon}_{dev} \right), \quad \psi^-(\boldsymbol{\epsilon}) = \frac{1}{2} K_n \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_-^2 -$$ -_Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods for phase field fracture models; Amor et al. (2009), Regularized formulation of the variational brittle fracture_ - -**strain_spectral_decomposition** -$$ -\psi^+(\boldsymbol{\epsilon}) = \frac{1}{2} \lambda \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+^2 + \mu \sum_{a=1}^3 \langle \epsilon_a \rangle_+^2, \quad \psi^-(\boldsymbol{\epsilon}) = \frac{1}{2} \lambda \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_-^2 + \mu \sum_{a=1}^3 \langle \epsilon_a \rangle_-^2 -$$ -_Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Zhang et al. (2022), Assessment of four strain energy decomposition methods_ - -**stress_spectral_decomposition** -$$ -\boldsymbol{\sigma}_0 = \mathbf{C} : \boldsymbol{\epsilon} = \sum_{a=1}^3 \sigma_a^0 \mathbf{m}_a \otimes \mathbf{m}_a, \quad \boldsymbol{\sigma}^+ = \sum_{a=1}^3 \langle \sigma_a^0 \rangle_+ \mathbf{m}_a \otimes \mathbf{m}_a, \quad \psi^\pm = \frac{1}{2} \boldsymbol{\sigma}^\pm : \boldsymbol{\epsilon} -$$ -_Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods for phase field fracture models_ - -**rankine_no_tension_effective_stress** -$$ -\bar{\sigma}_{eq} = \langle \bar{\sigma}_1 \rangle_+, \quad \bar{Y} = \frac{\bar{\sigma}_{eq}^2}{2 E_0} = \frac{\langle \bar{\sigma}_1 \rangle_+^2}{2 E_0} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**Notation:** -\boldsymbol{\epsilon}: small strain tensor; \boldsymbol{\epsilon}_{dev}: deviatoric strain tensor; \boldsymbol{\sigma}_0, \boldsymbol{\sigma}^+, \boldsymbol{\sigma}^-: undamaged, positive, and negative stress tensors; \epsilon_a, \sigma_a^0: principal strains and stresses; \bar{\sigma}_1: maximum principal effective stress; \bar{\sigma}_{eq}: Rankine equivalent stress; \psi^+, \psi^-: positive and negative strain energy density components; K_n: n-dimensional bulk modulus; \lambda, \mu: Lamé constants; E_0: Young's modulus; \mathcal{H}: energy release rate history field. - - -## 3. Algorithmic Implementation - -**strain-energy-split-evaluation-and-history-update** -$$ -\begin{algorithmic} -\State $At load step n+1 and element Gauss integration point, receive updated total strain tensor \boldsymbol{\epsilon}_{n+1}.$ -\If{$Energy split option == Volumetric-Deviatoric (StrainDe).$} -\State $Compute volumetric strain \text{tr}(\boldsymbol{\epsilon}_{n+1}) and deviatoric strain \boldsymbol{\epsilon}_{dev} = \boldsymbol{\epsilon}_{n+1} - \frac{1}{3}\text{tr}(\boldsymbol{\epsilon}_{n+1})\mathbf{I}.$ -\State $Evaluate positive strain energy: \psi^+ = \frac{1}{2} K_n \langle \text{tr}(\boldsymbol{\epsilon}_{n+1}) \rangle_+^2 + \mu (\boldsymbol{\epsilon}_{dev} : \boldsymbol{\epsilon}_{dev}).$ -\ElsIf{$Energy split option == Spectral (StrainSp / StressSp).$} -\State $Perform spectral Eigendecomposition of strain tensor \boldsymbol{\epsilon}_{n+1} = \sum_{a=1}^3 \epsilon_a \mathbf{n}_a \otimes \mathbf{n}_a or stress tensor \boldsymbol{\sigma}_0 = \sum_{a=1}^3 \sigma_a^0 \mathbf{m}_a \otimes \mathbf{m}_a.$ -\State $Evaluate positive tensile strain energy density \psi^+ = \frac{1}{2}\lambda \langle \text{tr}(\boldsymbol{\epsilon}_{n+1})\rangle_+^2 + \mu \sum_{a=1}^3 \langle \epsilon_a \rangle_+^2 (for StrainSp) or \psi^+ = \frac{1}{2} \boldsymbol{\sigma}^+ : \boldsymbol{\epsilon}_{n+1} (for StressSp).$ -\EndIf -\State $Update damage history field enforcing irreversibility: \mathcal{H}_{n+1} = \max\left(\mathcal{H}_n, \psi_{n+1}^+\right).$ -\State $Pass history field \mathcal{H}_{n+1} to phase-field evolution equation: \frac{g_c}{l_c}(d - l_c^2 \Delta d) = 2(1-d)\mathcal{H}_{n+1}.$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture_ - - -## 4. Known Pitfalls - -- **voldev-split-spurious-damage-under-pure-compression**: The volumetric-deviatoric strain energy decomposition (StrainDe) includes the full deviatoric strain energy \mu(\boldsymbol{\epsilon}_{dev} : \boldsymbol{\epsilon}_{dev}) in the positive driving energy \psi^+. Under pure hydrostatic compression or high compressive shear where no tensile principal strain exists, StrainDe continues to accumulate deviatoric strain energy, causing unphysical crack initiation and damage evolution under compression. _(Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods for phase field fracture models; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture)_ -- **misattributing-solver-speedup-to-energy-split**: Attributing a 3x-7x computational speedup to the choice of strain energy split is incorrect. Literature benchmarks show that energy split evaluation adds negligible overhead compared to global solver iterations. The documented 3x-7x speedup is achieved by switching from an alternating minimization (staggered) solver to a Broyden-Fletcher-Goldfarb-Shanno (BFGS) monolithic quasi-Newton solver. _(Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus)_ -- **spectral-split-tangent-discontinuity-at-zero-eigenvalues**: Spectral strain/stress energy decompositions involve Macaulay bracket projections \langle \cdot \rangle_\pm of principal values. When principal strains or stresses cross zero or when repeated eigenvalues occur, numerical derivative transitions in the constitutive tangent matrix can cause NR convergence slowdowns unless perturbation or C1 smoothing is applied. _(Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Zhang et al. (2022), Assessment of four strain energy decomposition methods)_ - -## References - -- Zhang, S., Jiang, W., and Tonks, M. R. (2022). Assessment of four strain energy decomposition methods for phase field fracture models using quasi-static and dynamic benchmark cases. Materials Theory, 6, 6. -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Amor, H., Marigo, J.-J., and Maurini, C. (2009). Regularized formulation of the variational brittle fracture with unilateral contact: Numerical experiments. Journal of the Mechanics and Physics of Solids, 57(8), 1209-1229. -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Wang, T., Ye, X., Liu, Z., Liu, X., Chu, D., and Zhuang, Z. (2020). A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration. Computational Mechanics, 65(5), 1305-1321. -- Molnar, G., Gravouil, A., Seghir, R., and Réthoré, J. (2020). An open-source Abaqus implementation of the phase-field method to study the effect of plasticity on the instantaneous fracture toughness in dynamic crack propagation. Computer Methods in Applied Mechanics and Engineering, 365, 113004. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-explicit-time-integration.md b/packages/akms/src/akms/_bundled/global_nodes/pf-explicit-time-integration.md deleted file mode 100644 index d861b6d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-explicit-time-integration.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -id: pf-explicit-time-integration -title: 'Explicit Phase-Field: Mass and Viscosity Scaling' -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- explicit -- mass-scaling -- viscosity -- GPU -- CFL -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-at2-regularization - type: feeds-into - weight: 0.5 -- to: pf-staggered-scheme - type: contradicts - weight: 0.0 -- to: pf-dynamic-brittle - type: feeds-into - weight: 0.5 -- to: pf-fem-implementation - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Explicit Phase-Field: Mass and Viscosity Scaling - -## Summary - -Formulation and implementation of explicit time integration schemes for coupled elastodynamics and diffusive phase-field fracture mechanics. Explicit phase-field frameworks decouple the mechanical displacement field u and phase-field damage variable d using staggered central-difference (for displacement) and forward-difference (for phase field) updates. By employing lumped diagonal mass M and artificial damping/capacity C matrices (constructed via row-sum techniques), explicit algorithms eliminate the need to solve large non-linear algebraic systems or re-assemble global tangent matrices at every increment. Artificial viscosity parameter \varpi = \omega l_c / g_f regularizes local phase-field evolution and prevents high-frequency spatial instabilities. To ensure stability, the time step size \Delta t is strictly bounded by the Courant-Friedrichs-Lewy (CFL) limit \Delta t \le h / c_p, where h is element size and c_p is dilatational wave speed. Furthermore, modern GPU-accelerated array programming frameworks (such as JAX-PF) leverage element-wise vectorization via jax.vmap to deliver 5x+ speedups over CPU-MPI solvers. - -## 1. Core Concept - -Explicit time integration for phase-field fracture provides a computationally decoupled, matrix-free solution architecture ideal for high-rate dynamic fracture, wave propagation, impact failure, and massive GPU parallelization. Unlike implicit monolithic or staggered schemes that require solving global stiffness systems with Newton-Raphson or quasi-Newton iterations, explicit schemes update solution states at time t_{n+1} directly from known state variables at time t_n. The mechanical sub-problem is integrated using the explicit central-difference method driven by lumped diagonal mass matrices M, while the phase-field evolution equation is integrated using the explicit forward-difference method governed by lumped capacity matrices C. To stabilize the forward-difference phase-field update and prevent numerical oscillations without violating thermodynamic irreversibility \dot{d} \ge 0, an artificial viscosity parameter \omega or viscous power term P_{vis} = \int \frac{\omega}{2} \dot{d}^2 d\Omega is introduced. Numerical stability requires satisfying the CFL condition \Delta t \le h / c_p; because resolving the regularized localization band requires fine spatial discretization (h \le l_c/2), explicit time steps are very small (\Delta t \sim 10^{-8} \text{ s} - 10^{-9} \text{ s}). GPU architectures exploit this element-wise decoupling using array vectorization to achieve extreme computational throughput. - -## 2. Mathematical Formulation - -**explicit_phase_field_governing_pde** -$$ -\varpi \dot{d} = (1-d)\mathcal{H} - (d - l_c^2 \Delta d), \quad \varpi = \frac{\omega l_c}{g_f} -$$ -_Source: Li et al. (2025), Phase field fracture in elastoplastic solids; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration_ - -**forward_difference_phase_field_update** -$$ -\mathbf{C} \dot{\mathbf{d}}_n = \mathbf{Y}_n \implies \dot{\mathbf{d}}_n = \mathbf{C}^{-1} \mathbf{Y}_n, \quad \mathbf{d}_{n+1} = \mathbf{d}_n + \Delta t_{n+1} \dot{\mathbf{d}}_n -$$ -_Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Li et al. (2025), Phase field fracture in elastoplastic solids; Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding_ - -**central_difference_displacement_explicit_step** -$$ -\mathbf{M} \ddot{\mathbf{u}}_n = \mathbf{F}_{ext, n} - \mathbf{F}_{int, n}, \quad \dot{\mathbf{u}}_{n+1/2} = \dot{\mathbf{u}}_{n-1/2} + \frac{\Delta t_{n+1} + \Delta t_n}{2} \ddot{\mathbf{u}}_n, \quad \mathbf{u}_{n+1} = \mathbf{u}_n + \Delta t_{n+1} \dot{\mathbf{u}}_{n+1/2} -$$ -_Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Li et al. (2025), Phase field fracture in elastoplastic solids_ - -**cfl_explicit_stability_bound** -$$ -\Delta t \le \Delta t_{crit} = \frac{h}{c_p}, \quad c_p = \sqrt{\frac{\lambda + 2\mu}{\rho}} -$$ -_Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Li et al. (2025), Phase field fracture in elastoplastic solids; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - -**Notation:** -d: scalar phase-field damage variable (d \in); \varpi: modified viscosity parameter (\varpi = \omega l_c / g_f); \omega: artificial viscosity parameter; l_c: regularization length scale parameter; g_f: critical fracture energy; \mathcal{H}: history variable field; \mathbf{d}: nodal phase-field vector; \mathbf{u}, \dot{\mathbf{u}}, \ddot{\mathbf{u}}: nodal displacement, velocity, and acceleration vectors; \mathbf{M}: lumped diagonal mass matrix; \mathbf{C}: lumped diagonal capacity/damping matrix; \mathbf{Y}: phase-field residual vector; \mathbf{F}_{int}, \mathbf{F}_{ext}: internal and external force vectors; \Delta t: explicit time step size; h: element mesh size; c_p: dilatational wave speed. - - -## 3. Algorithmic Implementation - -**explicit-staggered-phase-field-time-integration** -$$ -\begin{algorithmic} -\State $Initialize nodal displacement \mathbf{u}_0, velocity \dot{\mathbf{u}}_0, phase field \mathbf{d}_0 = \mathbf{0}, history field \mathcal{H}_0 = 0, and form lumped diagonal mass matrix \mathbf{M} and capacity matrix \mathbf{C} using row-sum lumping.$ -\For{$Loop over explicit time increments n = 0, 1, 2, \dots, N_{steps} with time step \Delta t_{n+1} \le h / c_p.$} -\State $At element Gauss integration points, evaluate strain \boldsymbol{\epsilon}_n = \mathbf{B}_u \mathbf{u}_n, positive strain energy \psi_0^+(\boldsymbol{\epsilon}_n), and update damage history field: \mathcal{H}_n = \max(\mathcal{H}_{n-1}, \psi_0^+(\boldsymbol{\epsilon}_n)).$ -\State $Compute phase-field residual vector \mathbf{Y}_n = -\mathbf{A}_{e=1}^{N_e} \int_{\Omega_e} \{ [d_n - 2(1-d_n)\mathcal{H}_n] \mathbf{N}_d^T + l_c^2 \mathbf{B}_d^T \nabla d_n \} d\Omega.$ -\State $Compute nodal phase-field rate \dot{\mathbf{d}}_n = \mathbf{C}^{-1} \mathbf{Y}_n and update phase field explicitly: \mathbf{d}_{n+1} = \mathbf{d}_n + \Delta t_{n+1} \dot{\mathbf{d}}_n.$ -\State $Evaluate degraded Cauchy stress \boldsymbol{\sigma}_n = [(1-d_n)^2 + k] \boldsymbol{\sigma}_0^+ + \boldsymbol{\sigma}_0^- and assemble internal force vector \mathbf{F}_{int, n} = \mathbf{A}_{e=1}^{N_e} \int_{\Omega_e} \mathbf{B}_u^T \boldsymbol{\sigma}_n d\Omega.$ -\State $Compute accelerations \ddot{\mathbf{u}}_n = \mathbf{M}^{-1} (\mathbf{F}_{ext, n} - \mathbf{F}_{int, n}), advance mid-step velocity \dot{\mathbf{u}}_{n+1/2} = \dot{\mathbf{u}}_{n-1/2} + \frac{\Delta t_{n+1} + \Delta t_n}{2} \ddot{\mathbf{u}}_n, and update displacement \mathbf{u}_{n+1} = \mathbf{u}_n + \Delta t_{n+1} \dot{\mathbf{u}}_{n+1/2}.$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Li et al. (2025), Phase field fracture in elastoplastic solids_ - -**gpu-vectorized-explicit-array-update** -$$ -\begin{algorithmic} -\State $Define global solution vectors for displacement \mathbf{U} and phase field \mathbf{D} mapped over structured FE grid.$ -\State $In GPU environment (JAX-PF framework), vectorize quadrature point strain and history field evaluations across all finite element cells simultaneously using array operations (e.g. jax.vmap).$ -\For{$Loop over explicit time steps n = 0, 1, 2, \dots, N_{steps}.$} -\State $Compute element-wise residual arrays \mathbf{r}(\mathbf{U}_n, \mathbf{D}_n) in parallel without constructing global tangent stiffness matrices.$ -\State $Apply diagonal mass and damping inverses \mathbf{M}^{-1} and \mathbf{C}^{-1} directly via element-wise array multiplication.$ -\State $Advance solution state \{\mathbf{U}_{n+1}, \mathbf{D}_{n+1}\} in a single vectorized GPU execution pass.$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Hu et al. (2025), Efficient GPU-computing simulation platform JAX-PF for differentiable phase field model_ - - -## 4. Known Pitfalls - -- **cfl-time-step-restriction-from-fine-mesh-resolution**: Phase-field fracture modeling requires fine element sizes h \le l_c/2 (or h \le b/5) inside localization zones to resolve sharp damage gradients. In explicit time integration, this fine spatial resolution drastically reduces the CFL stability limit (\Delta t \le h / c_p \sim 10^{-8} \text{ s} - 10^{-9} \text{ s}), demanding millions of time increments for long physical durations. _(Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding)_ -- **spurious-viscous-lag-from-excessive-artificial-damping**: If the artificial viscosity or damping parameter \varpi = \omega l_c / g_f is chosen too large, phase-field evolution lags significantly behind the mechanical stress state. This causes non-physical delay in crack initiation, artificially elevates peak load capacity, and distorts dynamic crack branching angles. _(Source: Li et al. (2025), Phase field fracture in elastoplastic solids; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration)_ -- **spurious-oscillations-from-undamped-explicit-phase-field**: Omitting viscous damping (\varpi = 0) in explicit forward-difference phase-field updates makes the local damage rate \dot{d} prone to numerical high-frequency oscillations and spatial instability across element boundaries, requiring artificial viscosity \omega > 0 or viscous power terms P_{vis} to smooth spatial phase-field rates. _(Source: Li et al. (2025), Phase field fracture in elastoplastic solids; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Zhang et al. (2022), Assessment of four strain energy decomposition methods)_ - -## References - -- Wang, T., Ye, X., Liu, Z., Liu, X., Chu, D., and Zhuang, Z. (2020). A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration. Computational Mechanics, 65(5), 1305-1321. -- Li, C., Liu, J., Dong, L., Wu, C., Steven, G., Li, Q., and Fang, J. (2025). Phase field fracture in elastoplastic solids: a stress-state, strain-rate, and orientation dependent model in explicit dynamics and its applications to additively manufactured metals. Journal of the Mechanics and Physics of Solids, 197, 105978. -- Hu, F., Guo, J., Niezgoda, S., Liu, W. K., and Cao, J. (2025). Efficient GPU-computing simulation platform JAX-PF for differentiable phase field model. arXiv pre-print. -- Zhang, H., Peng, H., Pei, X.-Y., Wu, J.-Y., Li, P., Tang, T.-G., Cai, L.-C., Li, Y., and Liu, H. (2023). Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals. Journal of the Mechanics and Physics of Solids, 172, 105186. -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-fem-implementation.md b/packages/akms/src/akms/_bundled/global_nodes/pf-fem-implementation.md deleted file mode 100644 index 24b2adf..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-fem-implementation.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: pf-fem-implementation -title: 'Phase-Field FEM: Weak Forms, Element Residuals, Mesh Requirements' -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- FEM -- weak-form -- element-residual -- mesh-requirement -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-at2-regularization - type: feeds-into - weight: 0.5 -- to: pf-staggered-scheme - type: feeds-into - weight: 0.5 -- to: fem-tl-weak-form - type: requires - weight: 1.0 -- to: pf-abaqus-umat-uel - type: feeds-into - weight: 0.5 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Phase-Field FEM: Weak Forms, Element Residuals, Mesh Requirements - -## Summary - -Finite element method (FEM) implementation framework for coupled phase-field fracture and damage mechanics. The continuum domain is spatially discretized using multi-field finite elements with C0-continuous isoparametric shape functions approximating both displacement u and scalar phase field d. The weak forms of mechanical momentum balance and diffusive phase-field evolution yield coupled algebraic residual vectors r_u and r_d. To prevent numerical locking and ensure convergence to the true sharp crack topology as regularization length scale b or l_c approaches zero, the finite element mesh size h inside the localization band B must satisfy h <= l_c / 2 (or h <= b/5). Damage irreversibility dot(d) >= 0 is efficiently enforced using historical maximum driving force fields H, avoiding complex active-set bound optimizations in standard FE solvers. - -## 1. Core Concept - -Implementing regularized phase-field fracture models within the finite element method requires solving a system of non-linear coupled partial differential equations governing mechanical equilibrium and diffusive crack interface evolution. In multi-field FE formulations, identical or compatible C0-continuous shape functions (e.g., bilinear quadrilateral Q4 or linear triangular T3 elements) interpolate nodal displacements a and nodal damage degrees of freedom a_bar. Derivation of element residuals and tangent stiffness matrices via Galerkin discretization reveals two primary computational challenges: (1) non-convexity of the total energy functional with respect to simultaneous variations of displacement and damage, which causes standard monolithic Newton-Raphson solvers to diverge during crack initiation and rapid propagation, and (2) strict spatial resolution demands, where element size h inside active damage bands must not exceed half the length scale l_c (h <= l_c/2) to prevent artificial mesh-alignment bias and locking. Staggered (alternate minimization) or quasi-Newton (BFGS) solvers, combined with history variable fields H = max(Y_0, max Y_tau) for damage irreversibility dot(d) >= 0, provide robust numerical convergence across brittle and ductile failure regimes. - -## 2. Mathematical Formulation - -**weak_form_mechanical_equilibrium** -$$ -\int_{\Omega} \mathbf{B}^T \boldsymbol{\sigma} d\Omega - \mathbf{f}_{ext} = \mathbf{0}, \quad \boldsymbol{\sigma} = \omega(d) \bar{\boldsymbol{\sigma}} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture_ - -**weak_form_phase_field_evolution** -$$ -\int_{B} \left[ \bar{\mathbf{N}}^T \left(-\omega'(d) \mathcal{H} + \frac{G_f}{c_{\alpha} b} \alpha'(d)\right) + \frac{2b}{c_{\alpha}} G_f \bar{\mathbf{B}}^T \nabla d \right] d\Omega = \mathbf{0} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**discretized_element_residuals** -$$ -\mathbf{r}_u = \mathbf{f}_{ext} - \int_{\Omega} \mathbf{B}^T \boldsymbol{\sigma} d\Omega, \quad \mathbf{r}_d = \int_{B} \left[ \bar{\mathbf{N}}^T \left( \omega'(d)\mathcal{H} + \frac{G_f}{c_{\alpha} b} \alpha'(d) \right) - \bar{\mathbf{B}}^T \mathbf{q} \right] d\Omega -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids_ - -**mesh_resolution_requirement** -$$ -h \le \frac{1}{2} l_c \quad \text{or} \quad h \le \frac{1}{5} b -$$ -_Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding_ - -**Notation:** -\mathbf{u}: displacement vector; d: scalar phase-field damage variable (d \in); \mathbf{a}: nodal displacement degrees of freedom; \bar{\mathbf{a}}: nodal phase-field degrees of freedom; \mathbf{N}, \bar{\mathbf{N}}: shape function matrices for displacement and phase field; \mathbf{B}, \bar{\mathbf{B}}: spatial gradient matrices for displacement and phase field; \boldsymbol{\sigma}: degraded Cauchy stress tensor; \bar{\boldsymbol{\sigma}}: undamaged effective stress tensor; \omega(d): energetic degradation function; \alpha(d): geometric crack function; b, l_c: regularization length scale parameters; c_{\alpha}: geometric scaling constant; G_f: critical fracture energy density; \mathcal{H}: energy release rate history field; h: finite element mesh size; \mathbf{r}_u, \mathbf{r}_d: global residual vectors. - - -## 3. Algorithmic Implementation - -**fe-spatial-discretization-and-residual-assembly** -$$ -\begin{algorithmic} -\State $Define multi-field finite element mesh \mathcal{T}_h subdividing domain \Omega into elements e \in \mathcal{E} with nodal displacement DOFs \mathbf{a} and phase-field DOFs \bar{\mathbf{a}}.$ -\For{$Loop over finite elements e = 1, 2, \dots, N_e.$} -\State $At Gauss integration points, evaluate shape function matrices \mathbf{N}, \bar{\mathbf{N}} and gradient matrices \mathbf{B}, \bar{\mathbf{B}}.$ -\State $Interpolate strain \boldsymbol{\epsilon}^h = \mathbf{B} \mathbf{a}^e, phase field d^h = \bar{\mathbf{N}} \bar{\mathbf{a}}^e, and phase-field gradient \nabla d^h = \bar{\mathbf{B}} \bar{\mathbf{a}}^e.$ -\State $Compute effective energy release rate \bar{Y} = \frac{\bar{\sigma}_{eq}^2}{2 E_0} and update history field \mathcal{H} = \max(\mathcal{H}_n, \bar{Y}).$ -\State $Evaluate degraded Cauchy stress \boldsymbol{\sigma} = \omega(d^h) \bar{\boldsymbol{\sigma}} and damage microforce flux \mathbf{q} = \frac{2b}{c_\alpha} G_f \nabla d^h.$ -\State $Assemble element displacement residual \mathbf{r}_u^e = \mathbf{f}_{ext}^e - \int_{\Omega_e} \mathbf{B}^T \boldsymbol{\sigma} d\Omega and element phase-field residual \mathbf{r}_d^e = \int_{B_e} \left[ \bar{\mathbf{N}}^T Q(d^h) - \bar{\mathbf{B}}^T \mathbf{q} \right] d\Omega.$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids_ - - -## 4. Known Pitfalls - -- **insufficient-mesh-resolution-locking-and-bias**: If the element size h in the expected crack localization zone exceeds l_c/2 or b/5, the spatial discretization fails to resolve the continuous phase-field gradient \nabla d. This results in severe mesh-bias, artificial overestimation of peak structural strength, and numerical locking. _(Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding)_ -- **monolithic-newton-divergence-from-non-convexity**: Standard monolithic Newton-Raphson solvers frequently fail to converge during crack initiation and rapid propagation increments. This instability stems from the non-convexity of the coupled energy functional with respect to u and d simultaneously. Solvers must utilize staggered alternate minimization, line search, or quasi-Newton (BFGS) algorithms. _(Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture)_ -- **tangent-matrix-asymmetry-in-hybrid-formulations**: In hybrid phase-field formulations where the history variable field \mathcal{H} replaces the instantaneous strain energy in the damage sub-problem to enforce damage irreversibility \dot{d} \ge 0, the inter-field coupling stiffness matrices K_{ud} and K_{du} are unsymmetric (K_{ud} \neq K_{du}^T). Solving monolithic systems with standard symmetric linear solvers causes non-convergence. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ - -## References - -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Tao, Z., Li, X., Tao, S., and Chen, Z. (2022). Phase-field modeling of 3D fracture in elasto-plastic solids based on the modified GTN theory and Abaqus subroutines UEL/UMAT. Engineering Fracture Mechanics, 260, 108196. -- Wang, T., Ye, X., Liu, Z., Liu, X., Chu, D., and Zhuang, Z. (2020). A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration. Computational Mechanics, 65(5), 1305-1321. -- Zhang, H., Peng, H., Pei, X.-Y., Wu, J.-Y., Li, P., Tang, T.-G., Cai, L.-C., Li, Y., and Liu, H. (2023). Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals. Journal of the Mechanics and Physics of Solids, 172, 105186. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-monolithic-bfgs.md b/packages/akms/src/akms/_bundled/global_nodes/pf-monolithic-bfgs.md deleted file mode 100644 index 9ed7139..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-monolithic-bfgs.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: pf-monolithic-bfgs -title: L-BFGS Monolithic Solver for Phase-Field Fracture -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- l-bfgs -- quasi-newton -- monolithic -- wu-2020 -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-monolithic-scheme - type: refines - weight: 0.7 -- to: pf-staggered-scheme - type: contradicts - weight: 0.0 -- to: pf-fem-implementation - type: feeds-into - weight: 0.5 -- to: pf-abaqus-umat-uel - type: feeds-into - weight: 0.5 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# L-BFGS Monolithic Solver for Phase-Field Fracture - -## Summary - -Monolithic Broyden-Fletcher-Goldfarb-Shanno (BFGS) quasi-Newton solver framework for coupled phase-field fracture mechanics. Traditional monolithic Newton-Raphson solvers diverge during crack initiation due to the non-convexity of the total energy functional with respect to simultaneous displacement and damage variations. While alternating minimization (staggered) solvers are robust, they require hundreds to thousands of iterations per increment during rapid crack propagation. The BFGS quasi-Newton monolithic algorithm resolves this by updating the inverse stiffness matrix using rank-two secant updates starting from an uncoupled, block-diagonal symmetric positive-definite initial matrix \tilde{\mathbf{K}}^{(0)} = \text{diag}(\mathbf{K}_{uu}, \mathbf{K}_{dd}). Applied across brittle fracture (AT1, AT2) and quasi-brittle failure (PF-CZM), the BFGS algorithm achieves identical solutions to staggered solvers with 3x-7x CPU time reductions and typical iteration counts of 10-50 per increment (reaching 100-300 during critical crack propagation steps). In commercial software such as Abaqus, the solver is activated using standard built-in keywords (*SOLUTION TECHNIQUE, TYPE=QUASI-NEWTON) combined with User Element (UEL) formulations. - -## 1. Core Concept - -In regularized phase-field fracture modeling, the total free energy functional E(\mathbf{u}, d) is strictly convex with respect to \mathbf{u} and d individually, but non-convex with respect to both fields simultaneously. Consequently, full Newton-Raphson monolithic schemes exhibit severe convergence failures due to negative eigenvalues in the coupled tangent stiffness. The BFGS quasi-Newton monolithic approach overcomes non-convexity by maintaining a symmetric, positive-definite approximation of the inverse stiffness matrix \tilde{\mathbf{K}}^{-1}. Starting each step or reformulating after a threshold of iterations (e.g., 8-10) with an uncoupled block-diagonal initial stiffness \tilde{\mathbf{K}}^{(0)} containing mechanical stiffness \mathbf{K}_{uu} and damage stiffness \mathbf{K}_{dd}, the algorithm updates the inverse operator via rank-two matrix corrections based on residual difference vectors \delta \mathbf{g} and solution increment vectors \delta \mathbf{z}. For PF-CZM models, positive-definiteness of \mathbf{K}_{dd} is guaranteed provided the regularization length scale satisfies b \le l_{ch} / 3 (where l_{ch} = E_0 G_f / f_t^2). In finite element packages like Abaqus, the BFGS solver operates via built-in Quasi-Newton solution keywords or UEL subroutines, avoiding the need for complex inter-field coupling derivatives while drastically outperforming staggered solvers. - -## 2. Mathematical Formulation - -**bfgs_coupled_residual_system** -$$ -\mathbf{g}(\mathbf{z}) = \begin{Bmatrix} \mathbf{r}_u(\mathbf{a}, \bar{\mathbf{a}}) \\ \mathbf{r}_d(\mathbf{a}, \bar{\mathbf{a}}) \end{Bmatrix} = \mathbf{0}, \quad \mathbf{z} = \begin{Bmatrix} \mathbf{a} \\ \bar{\mathbf{a}} \end{Bmatrix} -$$ -_Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - -**bfgs_initial_uncoupled_stiffness** -$$ -\tilde{\mathbf{K}}^{(0)} = \begin{bmatrix} \mathbf{K}_{uu} & \mathbf{0} \\ \mathbf{0} & \mathbf{K}_{dd} \end{bmatrix} -$$ -_Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - -**bfgs_rank_two_inverse_update** -$$ -\tilde{\mathbf{K}}_{k+1}^{-1} = \left(\mathbf{I} - \frac{\delta \mathbf{z} \delta \mathbf{g}^T}{\delta \mathbf{z}^T \delta \mathbf{g}}\right) \tilde{\mathbf{K}}_k^{-1} \left(\mathbf{I} - \frac{\delta \mathbf{g} \delta \mathbf{z}^T}{\delta \mathbf{z}^T \delta \mathbf{g}}\right) + \frac{\delta \mathbf{z} \delta \mathbf{z}^T}{\delta \mathbf{z}^T \delta \mathbf{g}} -$$ -_Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - -**pf_czm_positive_definiteness_condition** -$$ -b \le \frac{4}{\pi} \left( a_2 + p + \frac{1}{2} \right) l_{ch} \implies b \le \frac{1}{3} l_{ch} = \frac{1}{3} \frac{E_0 G_f}{f_t^2} -$$ -_Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - -**Notation:** -\mathbf{z}: unified nodal solution vector; \mathbf{a}: nodal displacement degrees of freedom; \bar{\mathbf{a}}: nodal damage degrees of freedom; \mathbf{r}_u, \mathbf{r}_d: displacement and damage residual vectors; \mathbf{g}: coupled global residual vector; \tilde{\mathbf{K}}^{(0)}: uncoupled initial block-diagonal stiffness matrix; \mathbf{K}_{uu}, \mathbf{K}_{dd}: mechanical and damage element tangent matrices; \delta \mathbf{z}: solution correction vector; \delta \mathbf{g}: residual change vector; b: regularization length scale parameter; l_{ch}: Irwin characteristic length. - - -## 3. Algorithmic Implementation - -**bfgs-monolithic-phase-field-solver** -$$ -\begin{algorithmic} -\State $At time step n+1, initialize iteration counter k = 0, solution guess \mathbf{z}^{(0)} = \mathbf{z}_n, and calculate initial coupled residual \mathbf{g}^{(0)} = [\mathbf{r}_u(\mathbf{z}^{(0)})^T, \mathbf{r}_d(\mathbf{z}^{(0)})^T]^T.$ -\State $Evaluate uncoupled block-diagonal initial stiffness matrix \tilde{\mathbf{K}}^{(0)} = \text{diag}(\mathbf{K}_{uu}(\mathbf{z}^{(0)}), \mathbf{K}_{dd}(\mathbf{z}^{(0)})) and invert to obtain \tilde{\mathbf{K}}^{(0)-1}.$ -\While{$Residual norm \|\mathbf{g}^{(k)}\| > \text{tol} \cdot \tilde{q}_{force}.$} -\State $Compute search direction step: \delta \mathbf{z} = \tilde{\mathbf{K}}^{(k)-1} \mathbf{g}^{(k)}.$ -\State $Perform line search with step length parameter s \in (0, 1] to satisfy residual reduction: \mathbf{z}^{(k+1)} = \mathbf{z}^{(k)} + s \delta \mathbf{z}.$ -\State $Update integration point strain energy \bar{Y} and history variable field: \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \bar{Y}).$ -\State $Evaluate updated global residual vector \mathbf{g}^{(k+1)} and residual increment \delta \mathbf{g} = \mathbf{g}^{(k+1)} - \mathbf{g}^{(k)}.$ -\If{$Iteration counter k \text{ mod } N_{reform} == 0 (e.g., N_{reform} = 8).$} -\State $Re-evaluate and invert uncoupled block-diagonal matrix: \tilde{\mathbf{K}}^{(k+1)-1} = \text{diag}(\mathbf{K}_{uu}^{-1}, \mathbf{K}_{dd}^{-1}).$ -\Else -\EndIf -\State $Increment iteration counter k \leftarrow k + 1.$ -\EndWhile -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - - -## 4. Known Pitfalls - -- **bfgs-matrix-indefiniteness-from-excessive-length-scale**: For cohesive phase-field models (PF-CZM), if the regularization length scale b exceeds Irwin's characteristic material bound b > l_ch / 3, the damage tangent stiffness matrix \mathbf{K}_{dd} loses positive-definiteness upon damage initiation (-\partial Q / \partial d < 0). This causes the BFGS inverse stiffness approximation \tilde{\mathbf{K}}^{-1} to become indefinite, leading to convergence failures. _(Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus)_ -- **misjudging-bfgs-iteration-counts-during-rapid-crack-propagation**: Assuming BFGS monolithic solvers converge in 5-15 iterations across all steps leads to improper time step controls. While BFGS requires only 10-50 iterations per increment during elastic loading and steady crack growth, critical increments with rapid crack propagation or multi-crack branching can require 100-300 iterations per increment. Setting Abaqus default iteration cutoffs too low causes unnecessary step cutbacks. _(Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus)_ -- **unneeded-interfield-coupling-derivatives-in-uel**: Attempting to manually derive and assemble off-diagonal coupled stiffness terms \mathbf{K}_{ud} and \mathbf{K}_{du} in UEL subroutines is unnecessary and error-prone. The BFGS monolithic scheme starts with uncoupled diagonal blocks \mathbf{K}_{uu} and \mathbf{K}_{dd} and automatically builds inter-field coupling via rank-two secant updates \delta \mathbf{z} and \delta \mathbf{g}. _(Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus)_ - -## References - -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Zhang, H., Pei, X.-Y., Peng, H., and Wu, J.-Y. (2021). Phase-field modeling of spontaneous shear bands in collapsing thick-walled cylinders. Engineering Fracture Mechanics, 249, 107706. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-monolithic-scheme.md b/packages/akms/src/akms/_bundled/global_nodes/pf-monolithic-scheme.md deleted file mode 100644 index dec2eec..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-monolithic-scheme.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: pf-monolithic-scheme -title: Monolithic Coupled Newton Solver for Phase-Field Fracture -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- monolithic -- newton -- coupled-solver -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-staggered-scheme - type: contradicts - weight: 0.0 -- to: pf-at2-regularization - type: feeds-into - weight: 0.5 -- to: pf-monolithic-bfgs - type: refines - weight: 0.7 -- to: pf-spectral-split - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Monolithic Coupled Newton Solver for Phase-Field Fracture - -## Summary - -Monolithic coupled Newton-Raphson solver framework for solving the non-linear simultaneous system of equations in phase-field fracture mechanics. In the monolithic formulation, mechanical equilibrium for displacement u and microforce balance for crack phase-field d are solved simultaneously in a single coupled algebraic system K \delta z = g. While monolithic Newton solvers achieve quadratic convergence when initial guesses lie within the convergence basin, standard Newton-Raphson schemes suffer from severe convergence difficulties and divergence during crack initiation and rapid crack growth due to the non-convexity of the total energy functional with respect to (u,d) jointly. Specialized globalization techniques such as non-conventional line searches (Gerasimov & De Lorenzis, 2016), modified Newton matrices (Wick, 2017), or primal-dual active set methods (Heister et al., 2015) are employed to stabilize monolithic Newton iterations, while full inter-field coupling tangents K_ud and K_du must be constructed. - -## 1. Core Concept - -The monolithic coupled solver approach formulates phase-field fracture as a unified initial boundary value problem where displacement degrees of freedom a and phase-field degrees of freedom \bar{a} are updated simultaneously using a fully coupled Jacobian matrix K. Owning to the variational formulation of rate-independent brittle fracture (Miehe et al., 2010), the monolithic tangent matrix is symmetric when derived from pure energy minimization. However, in hybrid formulations employing a historical energy field \mathcal{H} = \max(\mathcal{H}_n, \psi_0^+) to enforce damage irreversibility \dot{d} \ge 0, the off-diagonal coupling blocks K_ud and K_du become unsymmetric (K_ud \neq K_du^T). Although monolithic schemes possess full inter-field coupling and potential quadratic local convergence, their primary limitation is numerical instability: because the underlying free energy functional E(u,d) is non-convex with respect to displacement and damage fields simultaneously, standard Newton-Raphson solvers frequently fail to converge during crack initiation or abrupt crack propagation increments. In contrast to staggered solvers that often require over 1,000 iterations per increment in critical crack-propagation steps, monolithic Newton solvers require line-search stabilization or adaptive step-size controls to navigate non-convex energy landscapes. - -## 2. Mathematical Formulation - -**monolithic_coupled_residual** -$$ -\mathbf{g}(\mathbf{z}) = \begin{Bmatrix} \mathbf{r}_u(\mathbf{a}, \bar{\mathbf{a}}) \\ \mathbf{r}_d(\mathbf{a}, \bar{\mathbf{a}}) \end{Bmatrix} = \mathbf{0}, \quad \mathbf{z} = \begin{Bmatrix} \mathbf{a} \\ \bar{\mathbf{a}} \end{Bmatrix} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**monolithic_newton_linearized_system** -$$ -\begin{bmatrix} \mathbf{K}_{uu} & \mathbf{K}_{ud} \\ \mathbf{K}_{du} & \mathbf{K}_{dd} \end{bmatrix} \begin{Bmatrix} \delta \mathbf{a} \\ \delta \bar{\mathbf{a}} \end{Bmatrix} = \begin{Bmatrix} \mathbf{r}_u \\ \mathbf{r}_d \end{Bmatrix} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**monolithic_symmetric_tangent_variational** -$$ -\mathbf{K} = \int_{\Omega} \mathbf{B}^T \frac{\partial^2 \psi(\boldsymbol{\epsilon}, d)}{\partial \mathbf{z} \partial \mathbf{z}} \mathbf{B} d\Omega -$$ -_Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture_ - -**Notation:** -\mathbf{z}: combined nodal solution vector \{\mathbf{a}, \bar{\mathbf{a}}\}^T; \mathbf{a}: nodal displacement vector; \bar{\mathbf{a}}: nodal phase-field damage vector; \mathbf{r}_u, \mathbf{r}_d: mechanical and damage residual vectors; \mathbf{g}: monolithic global residual vector; \mathbf{K}_{uu}, \mathbf{K}_{dd}: mechanical and damage tangent stiffness blocks; \mathbf{K}_{ud}, \mathbf{K}_{du}: inter-field coupling tangent blocks; \boldsymbol{\sigma}: Cauchy stress tensor; \boldsymbol{\epsilon}: strain tensor; d: phase-field damage variable; \mathcal{H}: historical maximum energy release rate field. - - -## 3. Algorithmic Implementation - -**monolithic-coupled-newton-solver** -$$ -\begin{algorithmic} -\State $At load step n+1, initialize solution vector \mathbf{z}^{(0)} = \{\mathbf{a}_n, \bar{\mathbf{a}}_n\}^T and iteration index k = 0.$ -\For{$Loop over Newton-Raphson iterations k = 0, 1, 2, \dots, k_{max}.$} -\State $Evaluate element strain \boldsymbol{\epsilon}^{(k)} = \mathbf{B} \mathbf{a}^{(k)} and damage d^{(k)} = \bar{\mathbf{N}} \bar{\mathbf{a}}^{(k)} at integration points.$ -\State $Update energy driving force \bar{Y}^{(k)} and damage history field \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \bar{Y}^{(k)}).$ -\State $Assemble monolithic residual vector \mathbf{g}^{(k)} = [\mathbf{r}_u(\mathbf{z}^{(k)})^T, \mathbf{r}_d(\mathbf{z}^{(k)})^T]^T.$ -\If{$Residual norm \|\mathbf{g}^{(k)}\| \le \text{tol} \cdot \tilde{q}_{force} (Convergence criterion met).$} -\State $Accept step solution: \mathbf{z}_{n+1} = \mathbf{z}^{(k)}, \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \bar{Y}^{(k)}), and exit iteration.$ -\EndIf -\State $Assemble monolithic tangent stiffness matrix \mathbf{K}^{(k)} containing blocks \mathbf{K}_{uu}, \mathbf{K}_{ud}, \mathbf{K}_{du}, \mathbf{K}_{dd}.$ -\State $Solve fully coupled linear system for Newton update: \mathbf{K}^{(k)} \delta \mathbf{z} = \mathbf{g}^{(k)}.$ -\State $Perform line-search damping if required: \mathbf{z}^{(k+1)} = \mathbf{z}^{(k)} - s \cdot \delta \mathbf{z} with step length s \in (0, 1].$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Gerasimov and De Lorenzis (2016), A line search assisted monolithic approach for phase-field computing_ - - -## 4. Known Pitfalls - -- **monolithic-newton-divergence-from-nonconvexity**: The total free energy functional E(u,d) in phase-field fracture is non-convex with respect to simultaneous variations of displacement u and damage d. Consequently, standard monolithic Newton-Raphson algorithms frequently fail or diverge during crack initiation and rapid propagation increments unless line-search or quasi-Newton globalization techniques are used. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method)_ -- **interfield-tangent-matrix-asymmetry-in-hybrid-formulations**: In hybrid phase-field formulations that use a history variable field \mathcal{H} to enforce damage irreversibility \dot{d} \ge 0, the off-diagonal inter-field coupling blocks are unsymmetric (\mathbf{K}_{ud} \neq \mathbf{K}_{du}^T). Applying symmetric linear solvers (e.g., standard CG) directly to the monolithic system causes numerical breakdown. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ -- **problem-dependent-composite-solver-switching**: Attempting to build composite solvers that alternate between staggered iterations and monolithic Newton iterations (e.g. Farrell & Maurini, 2017) introduces problem-dependent transition heuristics. If the switch threshold is miscalibrated, the solver reverts to divergent Newton steps during critical crack initiation stages. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Farrell and Maurini (2017), Linear and nonlinear solvers for variational phase-field models of brittle fracture)_ - -## References - -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Molnar, G., Gravouil, A., Seghir, R., and Réthoré, J. (2020). An open-source Abaqus implementation of the phase-field method to study the effect of plasticity on the instantaneous fracture toughness in dynamic crack propagation. Computer Methods in Applied Mechanics and Engineering, 365, 113004. -- Gerasimov, T., and De Lorenzis, L. (2016). A line search assisted monolithic approach for phase-field computing of brittle fracture. Computer Methods in Applied Mechanics and Engineering, 312, 276-303. -- Farrell, P., and Maurini, C. (2017). Linear and nonlinear solvers for variational phase-field models of brittle fracture. International Journal for Numerical Methods in Engineering, 109(5), 648-667. -- Wick, T. (2017). Modified Newton methods for solving fully monolithic phase-field quasi-static brittle fracture propagation. Computer Methods in Applied Mechanics and Engineering, 325, 577-611. -- Heister, T., Wheeler, M. F., and Wick, T. (2015). A primal-dual active set method and predictor-corrector mesh adaptivity for computing fracture propagation using a phase-field approach. Computer Methods in Applied Mechanics and Engineering, 290, 466-495. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-porous-ductile.md b/packages/akms/src/akms/_bundled/global_nodes/pf-porous-ductile.md deleted file mode 100644 index 184c7b5..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-porous-ductile.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: pf-porous-ductile -title: Porous-Ductile Phase-Field (GTN + PF Coupling) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- GTN -- porous -- two-scale -- aldakheel -- ductile-fracture -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-ductile-plasticity-coupling - type: refines - weight: 0.7 -- to: damage-gtn-yield-function - type: requires - weight: 1.0 -- to: damage-gtn-void-evolution - type: requires - weight: 1.0 -- to: damage-nonlocal-gradient - type: requires - weight: 1.0 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Porous-Ductile Phase-Field (GTN + PF Coupling) - -## Summary - -Multi-scale formulation and implementation of coupled Gurson-Tvergaard-Needleman (GTN) porous plasticity and diffusive phase-field fracture mechanics. The framework bridges microvoid nucleation, growth, and coalescence at the microscopic scale with regularized crack initiation and macroscopic fracture propagation. Microvoid evolution degrades matrix yield strength via the GTN yield surface \Upsilon_G(\boldsymbol{\tau}, \bar{\sigma}) = 0, where void volume fraction \\(f = 1 - (1-f_0)/J^p\\) evolves with plastic volume expansion. Phase-field damage \\(s \in [1]\\) or \\(d \in [1]\\) is driven by plastic work dissipation \\(\psi^{pl}\\) alongside elastic strain energy \\(\psi^+\\), regularized by internal length scale \\(l_f\\) to eliminate pathological mesh sensitivity during softening. Modern extensions incorporate shear damage \\(D_s\\) into shear-modified GTN phase-field models (Tao et al., 2022) and multi-field finite element implementations (Dittmann et al., 2020). - -## 1. Core Concept - -Classical GTN continuum porous plasticity models effectively describe microvoid nucleation and growth under high stress triaxialities. However, upon reaching critical void coalescence, local loss of ellipticity causes extreme mesh dependency and non-physical localized energy dissipation. Coupling the GTN porous plasticity framework with a gradient-extended phase-field fracture model regularizes the failure process by introducing an internal length scale parameter \\(l_f\\). Microvoid growth governs early ductile softening and void volume fraction \\(f = 1 - (1-f_0)/J^p\\), while the phase-field variable \\(s\\) (or \\(d\\)) captures sharp macroscopic crack localization. The thermodynamic driving force \\(\mathcal{H}\\) incorporates accumulated plastic dissipation \\(\psi^{pl} = \int \boldsymbol{\sigma} : d\boldsymbol{\epsilon}^p\\) and tensile elastic strain energy \\(\psi^+\\). This two-scale mechanism prevents mesh alignment bias and accurately predicts failure transitions across low, medium, and high stress triaxialities in complex 2D and 3D structural components. - -## 2. Mathematical Formulation - -**gtn_yield_surface_phase_field** -$$ -\Upsilon_G(\boldsymbol{\tau}, \bar{\sigma}) = \frac{\sigma_{eq}^2}{\bar{\sigma}^2} + 2 q_1 f \cosh\left(\frac{3}{2} \frac{q_2 p}{\bar{\sigma}}\right) - \left(1 + (q_1 f)^2\right) = 0 -$$ -_Source: Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture in non-linear thermo-elasto-plastic solids; Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids_ - -**void_volume_fraction_kinematics** -$$ -f = \max\left\{f_0, 1 - \frac{1-f_0}{J^p}\right\}, \quad J^p = \det(\mathbf{F}^p) = \sqrt{\det(\mathbf{C}^p)} -$$ -_Source: Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture; Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids_ - -**porous_ductile_phase_field_driving_force** -$$ -\mathcal{H}_{n+1} = \max\left(\mathcal{H}_n, \psi_0^+ + \psi_0^{pl} - \psi_c\right), \quad \frac{g_c}{l_f}(s - l_f^2 \Delta s) = 2(1-s)\mathcal{H}_{n+1} -$$ -_Source: Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method_ - -**shear_modified_gtn_coupled_degradation** -$$ -D = q_1 f^* + D_s, \quad g(d, D_s, f) = (1-d)^{(a_1 + a_2 D_s + a_3 f)} -$$ -_Source: Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids based on the shear-modified GTN model_ - -**Notation:** -s, d: scalar phase-field damage variables (s, d \in); \boldsymbol{\tau}: Kirchhoff stress tensor; \mathbf{s}: deviatoric stress tensor; p: hydrostatic pressure; \sigma_{eq}: equivalent von Mises stress; \bar{\sigma}: matrix flow stress; f, f_0: current and initial void volume fractions; J^p: plastic volumetric determinant; \mathbf{F}, \mathbf{F}^e, \mathbf{F}^p: total, elastic, and plastic deformation gradients; \mathcal{H}: historical maximum energy release rate driving field; l_f, l_p: fracture and plastic internal length scales; g_c: critical fracture energy; D_s: shear damage variable. - - -## 3. Algorithmic Implementation - -**gtn-phase-field-staggered-return-mapping** -$$ -\begin{algorithmic} -\State $Initialize deformation mapping \boldsymbol{\phi}_0, plastic metric \mathbf{C}^p_0, void fraction f_0, hardening variable \alpha_0, damage s_0 = 0, and history field \mathcal{H}_0 = 0.$ -\For{$Loop over load/time increments n = 0, 1, 2, \dots, N_{steps}.$} -\State $Compute trial elastic state \mathbf{b}^{e, tr} = \mathbf{F}_{n+1} (\mathbf{C}^p_n)^{-1} \mathbf{F}_{n+1}^T and trial GTN yield function \Upsilon_G(\boldsymbol{\tau}^{tr}, \bar{\sigma}^{tr}).$ -\If{$\Upsilon_G \le 0 (Elastic step).$} -\State $Accept trial state, setting plastic multiplier \Delta \lambda^p = 0 and keeping f_{n+1} = f_n.$ -\Else -\State $Solve non-linear return-mapping equations for plastic multiplier \Delta \lambda^p, update plastic metric \mathbf{C}^p_{n+1}, and update void fraction f_{n+1} = \max\left\{f_0, 1 - (1-f_0)/J^p_{n+1}\right\}.$ -\EndIf -\State $Evaluate plastic dissipation work \psi_n^{pl} and elastic strain energy \psi_n^+, then update driving force history field \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \psi_n^+ + \psi_n^{pl} - \psi_c).$ -\State $Solve phase-field sub-problem for s_{n+1}: \frac{g_c}{l_f}(s_{n+1} - l_f^2 \Delta s_{n+1}) = 2(1-s_{n+1})\mathcal{H}_{n+1}.$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture; Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids_ - - -## 4. Known Pitfalls - -- **gtn-mesh-sensitivity-without-phase-field-regularization**: Classical GTN porous-plasticity models suffer from pathological mesh dependency and artificial strain localization when void growth causes plastic softening. Coupling GTN with a gradient phase-field fracture model introduces internal length scale l_f, regularizing void coalescence and maintaining well-posed governing equations. _(Source: Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture; Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids)_ -- **misattributing-gtn-phase-field-to-hydraulic-fracture-literature**: Confusing porous-ductile fracture (GTN void growth coupled with phase-field damage in metals) with hydraulic fracturing models in saturated porous media (e.g., Heider & Markert 2017/2018 for fluid-driven rock cracking) leads to incorrect kinematic assumptions and inappropriate fluid pressure coupling. _(Source: Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture in non-linear thermo-elasto-plastic solids; Zhang et al. (2022), Assessment of four strain energy decomposition methods)_ - -## References - -- Dittmann, M., Aldakheel, F., Schulte, J., Schmidt, F., Krüger, M., Wriggers, P., and Hesch, C. (2020). Phase-field modeling of porous-ductile fracture in non-linear thermo-elasto-plastic solids. Computer Methods in Applied Mechanics and Engineering, 361, 112730. -- Tao, Z., Li, X., Tao, S., and Chen, Z. (2022). Phase-field modeling of 3D fracture in elasto-plastic solids based on the shear-modified GTN model and Abaqus subroutines UEL/UMAT. Engineering Fracture Mechanics, 260, 108196. -- Aldakheel, F., Wriggers, P., and Miehe, C. (2018). A modified Gurson-type plasticity model at finite strains: formulation, numerical analysis and phase-field coupling. Computational Mechanics, 62(4), 815-833. -- Miehe, C., Kienle, D., Aldakheel, F., and Teichtmeister, S. (2016). Phase field modeling of fracture in porous plasticity: A variational gradient-extended Eulerian framework for the macroscopic analysis of ductile failure. Computer Methods in Applied Mechanics and Engineering, 312, 3-50. -- Borden, M. J., Hughes, T. J. R., Landis, C. M., Anvari, A., and Lee, I. J. (2016). A phase-field formulation for fracture in ductile materials: Finite deformation balance law derivation, plastic degradation, and stress triaxiality effects. Computer Methods in Applied Mechanics and Engineering, 312, 130-166. -- Molnar, G., Gravouil, A., Seghir, R., and Réthoré, J. (2020). An open-source Abaqus implementation of the phase-field method to study the effect of plasticity on the instantaneous fracture toughness in dynamic crack propagation. Computer Methods in Applied Mechanics and Engineering, 365, 113004. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-regularization-length.md b/packages/akms/src/akms/_bundled/global_nodes/pf-regularization-length.md deleted file mode 100644 index ad42493..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-regularization-length.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: pf-regularization-length -title: 'Phase-Field Regularization Length: Physics vs Numerics' -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- length-scale -- calibration -- sigma-c -- mesh-resolution -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-at1-regularization - type: refines - weight: 0.7 -- to: pf-at2-regularization - type: refines - weight: 0.7 -- to: pf-cohesive-zone - type: refines - weight: 0.7 -- to: pf-fem-implementation - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Phase-Field Regularization Length: Physics vs Numerics - -## Summary - -Theoretical formulation and calibration guidelines for the phase-field regularization length scale parameter (l_c, b, l_0). In classic Griffith brittle fracture formulations (e.g., Ambrosio-Tortorelli functional), the length scale b serves as a numerical regularization parameter that enables \Gamma-convergence to sharp crack surfaces as b \to 0. However, in standard AT1 and AT2 models, b acts simultaneously as a physical material length scale governing material tensile strength \sigma_c (where \sigma_c = \sqrt{3 E_0 G_f / (8 b)} for AT1 and \sigma_c \approx 0.325 \sqrt{E_0 G_f / b} for AT2). To resolve this duality and achieve true length-scale insensitivity in structural failure predictions, Wu's phase-field regularized cohesive zone model (PF-CZM) decouples b from tensile strength f_t via Irwin's characteristic length l_{ch} = E_0 G_f / f_t^2, provided b \le l_{ch}/3. Finite element spatial discretization requires mesh element sizes h \le l_c / 2 (or h \le b/5) inside active damage localization bands to resolve spatial phase-field gradients \nabla d without numerical locking or overestimating energy dissipation. - -## 1. Core Concept - -The phase-field regularization length scale (denoted variously as b, l, l_c, or l_0) governs the spatial spread of the diffusive crack surface density functional \Gamma_b(d) = \int_{\Omega} \frac{1}{c_{\alpha}} \left[ \frac{\alpha(d)}{b} + b |\nabla d|^2 \right] d\Omega. In standard AT1 and AT2 models, the length scale parameter is intrinsically tied to material failure strength \sigma_c. As a consequence, reducing b to model narrower crack bands artificially elevates the macroscopic peak load capacity, confusing numerical refinement with physical strengthening. Wu's unified phase-field damage theory resolves this limitation in PF-CZM by adopting a parabolic geometric crack function \alpha(d) = 2d - d^2 (c_{\alpha} = \pi) and calibrating the rational energetic degradation scaling parameter a_1 = \frac{4}{\pi} \frac{l_{ch}}{b} against Irwin's characteristic material length l_{ch} = E_0 G_f / f_t^2. So long as \\(b \le l_{ch}/3\\), the global load-displacement response and peak load become length-scale insensitive, allowing b to function purely as a numerical regularization parameter. Regardless of model choice, spatial finite element discretization must satisfy \\(h \le l_c/2\\) (or \\(h \le b/5\\)) inside active damage zones to avoid spatial locking and overestimating critical fracture energy. - -## 2. Mathematical Formulation - -**crack_surface_density_functional_general** -$$ -\Gamma_b(d) = \int_{\Omega} \frac{1}{c_{\alpha}} \left[ \frac{\alpha(d)}{b} + b |\nabla d|^2 \right] d\Omega -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture_ - -**at1_at2_strength_length_scale_relation** -$$ -\text{AT1: } \sigma_c = \sqrt{\frac{3 E_0 G_f}{8 b}}, \quad \text{AT2: } \sigma_c = \sqrt{\frac{27 E_0 G_f}{256 b}} \approx 0.325 \sqrt{\frac{E_0 G_f}{b}} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**pf_czm_decoupling_length_scale_bound** -$$ -a_1 = \frac{4}{\pi} \frac{l_{ch}}{b}, \quad l_{ch} = \frac{E_0 G_f}{f_t^2}, \quad b \le \frac{1}{3} l_{ch} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory_ - -**mesh_resolution_length_scale_bound** -$$ -h \le \frac{1}{2} l_c \quad \text{or} \quad h \le \frac{1}{5} b -$$ -_Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus_ - -**Notation:** -d: scalar phase-field damage variable (d \in [1]); b, l, l_c: regularization length scale parameter; c_{\alpha}: geometric scaling constant; \alpha(d): geometric crack function; \sigma_c: critical threshold/failure stress; f_t: uniaxial tensile strength; E_0: Young's modulus; G_f: critical energy release rate; l_{ch}: Irwin's characteristic material length (l_{ch} = E_0 G_f / f_t^2); h: finite element mesh size. - - -## 3. Algorithmic Implementation - -**length-scale-selection-and-mesh-calibration** -$$ -\begin{algorithmic} -\State $Input material parameters: Young's modulus E_0, fracture energy G_f, tensile strength f_t, and target domain geometry \Omega.$ -\If{$Model formulation == AT1 or AT2.$} -\State $Calculate regularization length scale directly from target material strength: b = \frac{3 E_0 G_f}{8 \sigma_c^2} \text{ (for AT1)} \text{ or } b = \frac{27 E_0 G_f}{256 \sigma_c^2} \text{ (for AT2)}.$ -\ElsIf{$Model formulation == PF-CZM.$} -\State $Compute Irwin's characteristic length l_{ch} = \frac{E_0 G_f}{f_t^2} and select regularization length scale b \le \frac{1}{3} l_{ch} based on available computational mesh limits.$ -\State $Compute PF-CZM degradation scaling parameter: a_1 = \frac{4}{\pi} \frac{l_{ch}}{b}.$ -\EndIf -\State $Set maximum element size in expected localization zones to satisfy h \le l_c / 2 (for AT1/AT2) or h \le b / 5 (for PF-CZM).$ -\State $Construct multi-field finite element mesh with local mesh refinement around notch tips or high stress concentration zones.$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture_ - - -## 4. Known Pitfalls - -- **at1-at2-length-scale-misinterpretation-as-pure-numerics**: In standard AT1 and AT2 phase-field models, treating length scale parameter b as an arbitrary numerical regularization parameter causes unphysical variation of material tensile strength \sigma_c \propto 1/\sqrt{b}. Arbitrarily reducing b to refine crack width artificially increases structural peak load. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ -- **coarse-mesh-locking-and-gc-overestimation**: Using element size h > l_c / 2 or h > b / 5 inside active damage localization bands fails to capture phase-field gradient \nabla d. This introduces severe spatial discretization locking, overestimating macroscopic peak load and critical fracture energy dissipation. _(Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus)_ -- **pf-czm-length-scale-upper-bound-violation**: In cohesive phase-field models (PF-CZM), setting regularization length scale b > l_{ch}/3 violates the positive-definiteness condition of the damage sub-problem (-\partial Q / \partial d \ge 0). This causes loss of length-scale insensitivity and leads to solver convergence failure. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ - -## References - -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Borden, M. J., Hughes, T. J. R., Landis, C. M., Anvari, A., and Lee, I. J. (2016). A phase-field formulation for fracture in ductile materials: Finite deformation balance law derivation, plastic degradation, and stress triaxiality effects. Computer Methods in Applied Mechanics and Engineering, 312, 130-166. -- Pham, K., Amor, H., Marigo, J.-J., and Maurini, C. (2011). Gradient damage models and their use to approximate brittle fracture. International Journal of Damage Mechanics, 20(4), 618-652. -- Dittmann, M., Aldakheel, F., Schulte, J., Schmidt, F., Krüger, M., Wriggers, P., and Hesch, C. (2020). Phase-field modeling of porous-ductile fracture in non-linear thermo-elasto-plastic solids. Computer Methods in Applied Mechanics and Engineering, 361, 112730. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-spallation.md b/packages/akms/src/akms/_bundled/global_nodes/pf-spallation.md deleted file mode 100644 index 8337494..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-spallation.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: pf-spallation -title: Phase-Field for Spallation Fracture -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- spallation -- plate-impact -- hugoniot-tensile -- zhang-2023 -- han-2024 -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-dynamic-brittle - type: refines - weight: 0.7 -- to: pf-dynamic-shear-bands - type: refines - weight: 0.7 -- to: damage-spall - type: refines - weight: 0.7 -- to: eos-mie-gruneisen - type: requires - weight: 1.0 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Phase-Field for Spallation Fracture - -## Summary - -Phase-field formulation and explicit dynamic modeling of spallation fracture in metals subjected to high-velocity impact, shock waves, and explosive loading. Spallation occurs when compressive shock waves reflect off free surfaces as tensile release (rarefaction) waves; where opposing release waves intersect, internal tensile stresses exceed the material dynamic spall strength \sigma_{spall}, inducing rapid void/microcrack nucleation, growth, and planar coalescence. The phase-field framework models spallation by regularizing sharp spall surfaces with a diffusive scalar damage variable d_I (or d_t), driven by historical maximum tensile volumetric strain energy \psi_{vol}^+ = \frac{1}{2} K \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+^2. By split-degrading tensile volumetric and deviatoric stresses while leaving compressive hydrostatic pressure p > 0 undegraded, the formulation captures complex spallation patterns—including single-layer spall, multi-layer spall, and spall-induced pullback velocity signals—without requiring pre-defined crack paths or complex interface tracking algorithms. - -## 1. Core Concept - -Dynamic spallation fracture is a prominent failure mode in impact mechanics, characterized by internal planar cracking generated by intersecting tensile release waves. Traditional sharp-interface tracking, cohesive surface elements, or element-erosion methods encounter severe difficulties when modeling multi-layer spallation, complex multi-crack interactions, and three-dimensional fragmentation because crack paths and nucleation sites are not known a priori. The phase-field approach regularizes spall discontinuities using an internal length scale b_I (or l_c), representing spall damage via a continuous order parameter d_I \in [1]. To capture the physics of dynamic wave propagation, the strain energy functional is decomposed into compressive volumetric, tensile volumetric \psi_{vol}^+, and deviatoric components. Only tensile volumetric energy drives the spall phase field d_I, ensuring that heavy hydrostatic shock compression does not cause artificial damage. On the specimen boundary, spallation manifests as a diagnostic "pullback signal" in free-surface velocity profiles, where the velocity drop \Delta v_{pb} directly correlates with the dynamic spall strength \sigma_{spall} \approx \frac{1}{2} \rho_0 c_0 \Delta v_{pb}. Coupled double phase-field models (Zhang et al., 2023) further integrate spall damage d_I with shear localization d_{II}, capturing complete dynamic failure from shock reflection to shell fragmentation. - -## 2. Mathematical Formulation - -**spall_driving_force_history** -$$ -\mathcal{H}_I(\mathbf{x}, t) = \max_{\tau \in [0, t]} \psi_{vol}^+(\mathbf{x}, \tau), \quad \psi_{vol}^+ = \frac{1}{2} K \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+^2 -$$ -_Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding; Zhang et al. (2021b), A Phase-field model for spall fracture_ - -**spall_phase_field_governing_pde** -$$ -\eta_I \dot{d}_I = 2 b_I^2 \Delta d_I - (1-d_{II}) \omega_I'(d) \mathcal{H}_I - \alpha_I'(d_I) -$$ -_Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals_ - -**spall_stress_tensor_volumetric_split** -$$ -\boldsymbol{\sigma} = -\omega_t(d) H(-p) p \mathbf{I} - H(p) p \mathbf{I} + \omega_s(d) \mathbf{s} -$$ -_Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding; Zhang et al. (2021a), Phase-field modeling of spontaneous shear bands_ - -**spall_pullback_velocity_relation** -$$ -\sigma_{spall} \approx \frac{1}{2} \rho_0 c_0 \Delta v_{pb}, \quad \Delta v_{pb} = v_{max} - v_{min} -$$ -_Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding; Li et al. (2025), Phase field fracture in elastoplastic solids_ - -**Notation:** -d_I, d_t: scalar spall phase-field damage variable; d_{II}, d_s: scalar shear band damage variable; d: combined damage variable; \boldsymbol{\sigma}: Cauchy stress tensor; \mathbf{s}: deviatoric Cauchy stress tensor; p: hydrostatic pressure; K: material bulk modulus; \psi_{vol}^+, \psi_{vol}^-: tensile and compressive volumetric strain energy densities; \mathcal{H}_I: spall history driving field; b_I, l_c: spall length scale parameter; \eta_I: artificial viscosity parameter; \rho_0: mass density; c_0: bulk sound speed; \Delta v_{pb}: pullback velocity signal. - - -## 3. Algorithmic Implementation - -**explicit-dynamic-spall-phase-field-solver** -$$ -\begin{algorithmic} -\State $Initialize nodal displacement \mathbf{u}_0, velocity \dot{\mathbf{u}}_0, spall phase field d_{I,0} = 0, history field \mathcal{H}_{I,0} = 0, and lumped mass matrix \mathbf{M}.$ -\For{$Loop over explicit time increments n = 0, 1, 2, \dots, N_{steps} with time step \Delta t \le h / c_p.$} -\State $Advance nodal displacement \mathbf{u}_{n+1} using explicit central-difference integration and evaluate element strain \boldsymbol{\epsilon}_{n+1}.$ -\State $Compute tensile volumetric strain energy \psi_{vol}^+ = \frac{1}{2} K \langle \text{tr}(\boldsymbol{\epsilon}_{n+1}) \rangle_+^2 at integration points.$ -\State $Update spall history driving field: \mathcal{H}_{I, n+1} = \max\left(\mathcal{H}_{I, n}, \psi_{vol}^+\right).$ -\State $Solve spall phase-field update for d_{I, n+1}: \eta_I \dot{d}_I = 2 b_I^2 \Delta d_I - \omega_I'(d_{I, n}) \mathcal{H}_{I, n+1} - \alpha_I'(d_{I, n}).$ -\State $Evaluate degraded Cauchy stress \boldsymbol{\sigma}_{n+1} leaving compressive pressure undegraded, and assemble internal force vector \mathbf{F}_{int, n+1}.$ -\State $Update nodal accelerations \ddot{\mathbf{u}}_{n+1} = \mathbf{M}^{-1}(\mathbf{F}_{ext, n+1} - \mathbf{F}_{int, n+1}) and advance velocities \dot{\mathbf{u}}_{n+1}.$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture_ - - -## 4. Known Pitfalls - -- **compressive-pressure-degradation-in-shock-wave-propagation**: Degrading compressive pressure during high-velocity impact shock wave propagation causes non-physical material volume collapse and distorts reflected tensile wave profiles. Compressive pressure under p > 0 must remain strictly undegraded while tensile volumetric strain energy drives spall phase-field d_I. _(Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding; Zhang et al. (2021a), Phase-field modeling of spontaneous shear bands)_ -- **spurious-spall-planes-from-unresolved-wave-fronts**: Using finite element sizes h > b_I/2 across the plate thickness causes numerical dispersion of steep shock and release wave fronts. This produces spurious secondary stress peaks, leading to artificial multi-layer spallation or incorrect pullback velocity amplitudes. _(Source: Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture)_ - -## References - -- Zhang, H., Peng, H., Pei, X.-Y., Wu, J.-Y., Li, P., Tang, T.-G., Cai, L.-C., Li, Y., and Liu, H. (2023). Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals. Journal of the Mechanics and Physics of Solids, 172, 105186. -- Zhang, H., Peng, H., Pei, X.-Y., Li, P., Tang, T.-G., and Cai, L.-C. (2021b). A Phase-field model for spall fracture. Journal of Applied Physics, 129, 125903. -- Zhang, H., Pei, X.-Y., Peng, H., and Wu, J.-Y. (2021a). Phase-field modeling of spontaneous shear bands in collapsing thick-walled cylinders. Engineering Fracture Mechanics, 249, 107706. -- Li, C., Liu, J., Dong, L., Wu, C., Steven, G., Li, Q., and Fang, J. (2025). Phase field fracture in elastoplastic solids: a stress-state, strain-rate, and orientation dependent model in explicit dynamics and its applications to additively manufactured metals. Journal of the Mechanics and Physics of Solids, 197, 105978. -- Wang, T., Ye, X., Liu, Z., Liu, X., Chu, D., and Zhuang, Z. (2020). A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration. Computational Mechanics, 65(5), 1305-1321. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-spectral-split.md b/packages/akms/src/akms/_bundled/global_nodes/pf-spectral-split.md deleted file mode 100644 index 18471ac..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-spectral-split.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: pf-spectral-split -title: Spectral Energy Decomposition (Miehe) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- spectral-split -- energy-decomposition -- miehe -- tension-compression -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-at2-regularization - type: feeds-into - weight: 0.5 -- to: pf-at1-regularization - type: feeds-into - weight: 0.5 -- to: pf-voldev-split - type: contradicts - weight: 0.0 -- to: pf-energy-split-comparison - type: feeds-into - weight: 0.5 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Spectral Energy Decomposition (Miehe) - -## Summary - -Formulation, physical behavior, and numerical implementation of Miehe's spectral strain energy decomposition in phase-field fracture mechanics. To model physical unilateral crack-closure contact and prevent unphysical crack propagation under compressive stress states, Miehe et al. (2010) introduced a spectral decomposition of the strain tensor \boldsymbol{\epsilon} = \sum_{a=1}^3 \epsilon_a \mathbf{n}_a \otimes \mathbf{n}_a into positive (tensile) and negative (compressive) principal parts using Macaulay brackets \langle \cdot \rangle_\pm. The positive strain energy density \psi_0^+(\boldsymbol{\epsilon}) = \frac{1}{2}\lambda \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+^2 + \mu \sum_{a=1}^3 \langle \epsilon_a \rangle_+^2 is degraded by (1-d)^2 to drive phase-field evolution, while compressive energy \psi_0^- remains undegraded. Benchmark evaluations (Zhang et al., 2022) confirm that spectral decomposition provides superior accuracy in mixed-mode and compressive fracture scenarios compared to volumetric-deviatoric splits. Numerical stabilization methods, such as eigenvalue perturbation (\delta \approx 0.10) for degenerate states, resolve potential derivative stiffness matrix ill-conditioning (Molnar et al., 2020). - -## 1. Core Concept - -In variational phase-field fracture, applying degradation g(d) = (1-d)^2 indiscriminately to total strain energy causes cracks to nucleate and propagate under pure hydrostatic compression or shear-compression loading. Miehe's spectral energy decomposition resolves this physical inconsistency by performing an Eigendecomposition of the small strain tensor \boldsymbol{\epsilon} (or Cauchy stress tensor \boldsymbol{\sigma}_0) into orthogonal principal directions \mathbf{n}_a and principal strains \epsilon_a. The strain energy density \psi_0(\boldsymbol{\epsilon}) is additively split into a crack-driving tensile component \psi_0^+ (composed of positive principal strains \langle \epsilon_a \rangle_+) and a non-driving compressive component \psi_0^- (composed of negative principal strains \langle \epsilon_a \rangle_-). As a result, when crack faces close under compressive loads, the compressive stiffness is fully restored, preventing interpenetration. While spectral decomposition requires evaluating 3x3 local Eigendecompositions at integration points, literature benchmarks demonstrate that local spectral calculations add minimal overhead; global computational performance is determined by global solver selection (staggered vs. monolithic BFGS) rather than the energy split itself. - -## 2. Mathematical Formulation - -**strain_spectral_energy_split** -$$ -\psi_0^+(\boldsymbol{\epsilon}) = \frac{1}{2}\lambda \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+^2 + \mu \sum_{a=1}^3 \langle \epsilon_a \rangle_+^2, \quad \psi_0^-(\boldsymbol{\epsilon}) = \frac{1}{2}\lambda \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_-^2 + \mu \sum_{a=1}^3 \langle \epsilon_a \rangle_-^2 -$$ -_Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Zhang et al. (2022), Assessment of four strain energy decomposition methods_ - -**spectral_degraded_stress_tensor** -$$ -\boldsymbol{\sigma} = [(1-d)^2 + k] \boldsymbol{\sigma}_0^+ + \boldsymbol{\sigma}_0^-, \quad \boldsymbol{\sigma}_0^\pm = \lambda \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_\pm \mathbf{I} + 2\mu \sum_{a=1}^3 \langle \epsilon_a \rangle_\pm \mathbf{n}_a \otimes \mathbf{n}_a -$$ -_Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method_ - -**stress_spectral_decomposition_variant** -$$ -\boldsymbol{\sigma}_0 = \mathbf{C} : \boldsymbol{\epsilon} = \sum_{a=1}^3 \sigma_a^0 \mathbf{m}_a \otimes \mathbf{m}_a, \quad \boldsymbol{\sigma}^+ = \sum_{a=1}^3 \langle \sigma_a^0 \rangle_+ \mathbf{m}_a \otimes \mathbf{m}_a, \quad \psi^\pm = \frac{1}{2} \boldsymbol{\sigma}^\pm : \boldsymbol{\epsilon} -$$ -_Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods for phase field fracture models_ - -**spectral_eigenvalue_perturbation** -$$ -\text{If } |\epsilon_1 - \epsilon_2| \le \text{tol}, \quad \epsilon_2' = (1 + \delta) \epsilon_2, \quad \boldsymbol{\epsilon}' = \mathbf{V} \hat{\boldsymbol{\epsilon}}' \mathbf{V}^T -$$ -_Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Zhang et al. (2022), Assessment of four strain energy decomposition methods_ - -**Notation:** -\boldsymbol{\epsilon}: small strain tensor; \epsilon_a: principal strain eigenvalues; \mathbf{n}_a: principal strain eigenvectors; \boldsymbol{\sigma}_0, \boldsymbol{\sigma}_0^+, \boldsymbol{\sigma}_0^-: undamaged, positive, and negative stress tensors; \psi_0^+, \psi_0^-: positive (tensile) and negative (compressive) strain energy density components; \lambda, \mu: Lamé elastic constants; d: scalar phase-field damage variable (d \in); \langle \cdot \rangle_\pm: Macaulay bracket functions. - - -## 3. Algorithmic Implementation - -**spectral-decomposition-and-constitutive-update** -$$ -\begin{algorithmic} -\State $At finite element integration point, receive trial total strain tensor \boldsymbol{\epsilon}_{n+1}.$ -\State $Compute trace \text{tr}(\boldsymbol{\epsilon}_{n+1}) = \epsilon_{11} + \epsilon_{22} + \epsilon_{33} and Macaulay brackets \langle \text{tr}(\boldsymbol{\epsilon}_{n+1}) \rangle_\pm.$ -\State $Solve 3D eigenvalue problem for strain tensor: \boldsymbol{\epsilon}_{n+1} \mathbf{n}_a = \epsilon_a \mathbf{n}_a for a \in \{1, 2, 3\}.$ -\If{$Eigenvalue degeneracy detected (|\epsilon_a - \epsilon_b| \le 10^{-7} \text{ for } a \neq b).$} -\State $Apply eigenvalue perturbation \epsilon_b' = (1 + \delta) \epsilon_b with \delta = 0.10 and reconstruct strain tensor \boldsymbol{\epsilon}' = \mathbf{V} \hat{\boldsymbol{\epsilon}}' \mathbf{V}^T.$ -\EndIf -\State $Evaluate positive and negative strain energy densities: \psi_0^+ = \frac{1}{2}\lambda \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+^2 + \mu \sum_{a=1}^3 \langle \epsilon_a \rangle_+^2, \psi_0^- = \frac{1}{2}\lambda \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_-^2 + \mu \sum_{a=1}^3 \langle \epsilon_a \rangle_-^2.$ -\State $Update energy release rate history field: \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \psi_0^+).$ -\State $Evaluate degraded Cauchy stress tensor: \boldsymbol{\sigma}_{n+1} = [(1-d_{n+1})^2 + k] \boldsymbol{\sigma}_0^+ + \boldsymbol{\sigma}_0^-.$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Zhang et al. (2022), Assessment of four strain energy decomposition methods_ - - -## 4. Known Pitfalls - -- **spurious-damage-under-compression-without-spectral-split**: Omitting spectral or positive-negative strain energy decomposition allows purely compressive or compression-shear hydrostatic states to generate damage. The spectral split ensures that only positive principal strains drive phase-field damage evolution, preventing unphysical crack growth under compressive confinement. _(Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Zhang et al. (2022), Assessment of four strain energy decomposition methods)_ -- **degenerate-eigenvalue-numerical-instability**: When two or three principal strains are identical (\epsilon_a \approx \epsilon_b), numerical derivatives in the constitutive tangent matrix can suffer floating-point instability or loss of convergence in Newton solvers. Implementing eigenvalue perturbation (\delta \sim 0.10) or restricting matrix updates to early Newton iterations stabilizes calculation. _(Source: Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method; Zhang et al. (2022), Assessment of four strain energy decomposition methods)_ -- **misattributing-solver-speed-to-spectral-eigendecomposition**: Attributing global computational overhead or slowdowns to local 3x3 eigendecompositions is incorrect. Literature benchmarks show that local spectral Eigendecomposition adds negligible runtime compared to global linear system solves; global computational speed is governed by solver selection (staggered vs. monolithic BFGS). _(Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Zhang et al. (2022), Assessment of four strain energy decomposition methods)_ - -## References - -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Zhang, S., Jiang, W., and Tonks, M. R. (2022). Assessment of four strain energy decomposition methods for phase field fracture models using quasi-static and dynamic benchmark cases. Materials Theory, 6, 6. -- Molnar, G., Gravouil, A., Seghir, R., and Réthoré, J. (2020). An open-source Abaqus implementation of the phase-field method to study the effect of plasticity on the instantaneous fracture toughness in dynamic crack propagation. Computer Methods in Applied Mechanics and Engineering, 365, 113004. -- Borden, M. J., Hughes, T. J. R., Landis, C. M., Anvari, A., and Lee, I. J. (2016). A phase-field formulation for fracture in ductile materials: Finite deformation balance law derivation, plastic degradation, and stress triaxiality effects. Computer Methods in Applied Mechanics and Engineering, 312, 130-166. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-staggered-scheme.md b/packages/akms/src/akms/_bundled/global_nodes/pf-staggered-scheme.md deleted file mode 100644 index 7beb098..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-staggered-scheme.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -id: pf-staggered-scheme -title: Staggered (Alternate Minimization) Scheme for Phase-Field Fracture -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- staggered -- alternate-minimization -- miehe -- history-variable -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-at2-regularization - type: feeds-into - weight: 0.5 -- to: pf-at1-regularization - type: feeds-into - weight: 0.5 -- to: pf-monolithic-scheme - type: contradicts - weight: 0.0 -- to: pf-spectral-split - type: requires - weight: 1.0 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Staggered (Alternate Minimization) Scheme for Phase-Field Fracture - -## Summary - -The staggered (alternate minimization / operator split) scheme is an iterative decoupling algorithm for solving the non-linear coupled equations of phase-field fracture mechanics. Developed by Bourdin et al. (2000, 2008) and adapted by Miehe et al. (2010), the scheme decouples mechanical momentum balance for displacement u and microforce balance for damage d into two separate, strictly convex sub-problems solved alternatingly within each load increment. Damage irreversibility \dot{d} \ge 0 is efficiently enforced by passing a historical maximum strain energy release rate field \mathcal{H} between sub-problems. Although the staggered scheme is highly robust against divergence and avoids the non-convex energy states that cause standard Newton monolithic schemes to fail, its first-order (Gauss-Seidel) convergence rate makes it computationally inefficient, frequently requiring over 1,000 iterations per increment during rapid crack propagation. - -## 1. Core Concept - -The total free energy functional in phase-field fracture is non-convex with respect to displacement u and phase-field damage d simultaneously, causing standard monolithic Newton-Raphson solvers to diverge. The staggered (alternate minimization) scheme overcomes this by exploiting the partial convexity of the free energy functional with respect to u and d individually. In each staggered iteration, the displacement sub-problem is solved for u holding d fixed, updating the strain energy field. Next, the maximum historical positive strain energy density \mathcal{H} = \max(\mathcal{H}_n, \psi_0^+) is evaluated at Gauss integration points to enforce damage irreversibility \dot{d} \ge 0 without box constraints, and the linear damage sub-problem is solved for d holding u fixed. While the staggered algorithm exhibits exceptional numerical robustness, it suffers from a first-order convergence rate. During critical steps involving rapid crack nucleation, propagation, or multi-crack branching, the staggered scheme requires hundreds or thousands of iterations, incurring a 3x to 7x CPU penalty compared to monolithic quasi-Newton (BFGS) solvers. - -## 2. Mathematical Formulation - -**staggered_mechanical_subproblem** -$$ -\mathbf{K}_{uu}(\mathbf{a}^{(k-1)}, \bar{\mathbf{a}}^{(k-1)}) \delta \mathbf{a} = \mathbf{r}_u(\mathbf{a}^{(k-1)}, \bar{\mathbf{a}}^{(k-1)}), \quad \mathbf{a}^{(k)} = \mathbf{a}^{(k-1)} + \delta \mathbf{a} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture_ - -**staggered_phase_field_subproblem** -$$ -\mathbf{K}_{dd}(\bar{\mathbf{a}}^{(k-1)}) \delta \bar{\mathbf{a}} = \bar{\mathbf{r}}_d(\mathbf{a}^{(k)}, \bar{\mathbf{a}}^{(k-1)}), \quad \bar{\mathbf{a}}^{(k)} = \bar{\mathbf{a}}^{(k-1)} + \delta \bar{\mathbf{a}} -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Tao et al. (2022), Phase-field modeling of 3D fracture in elasto-plastic solids_ - -**history_variable_irreversibility_enforcement** -$$ -\mathcal{H}_{n+1}(\mathbf{x}) = \max\left( \mathcal{H}_n(\mathbf{x}), \psi_0^+(\boldsymbol{\epsilon}_{n+1}(\mathbf{x})) \right) -$$ -_Source: Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture; Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method_ - -**staggered_over_relaxation_acceleration** -$$ -d^{(k)} = \omega_{rel} \tilde{d}^{(k)} + (1 - \omega_{rel}) d^{(k-1)}, \quad \omega_{rel} > 1 -$$ -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Farrell and Maurini (2017), Linear and nonlinear solvers for variational phase-field models of brittle fracture_ - -**Notation:** -\mathbf{a}: nodal displacement degrees of freedom; \bar{\mathbf{a}}, d: nodal and scalar phase-field damage variables; \mathbf{K}_{uu}, \mathbf{K}_{dd}: mechanical and damage tangent stiffness matrices; \mathbf{r}_u, \bar{\mathbf{r}}_d: mechanical and damage residual vectors; \mathcal{H}: history variable field of maximum strain energy release rate; \psi_0^+: positive elastic strain energy density; \omega_{rel}: over-relaxation acceleration parameter; k: staggered iteration index. - - -## 3. Algorithmic Implementation - -**iterative-staggered-alternate-minimization-solver** -$$ -\begin{algorithmic} -\State $At load step n+1, initialize solution guesses \mathbf{a}^{(0)} = \mathbf{a}_n, \bar{\mathbf{a}}^{(0)} = \bar{\mathbf{a}}_n, and iteration counter k = 1.$ -\While{$Residual/damage change norm \max(\|\mathbf{r}_u\|, \|\bar{\mathbf{r}}_d\|) > \text{tol} \text{ or } \|\bar{\mathbf{a}}^{(k)} - \bar{\mathbf{a}}^{(k-1)}\|_\infty > \text{tol}_d.$} -\State $Solve mechanical displacement sub-problem for \mathbf{a}^{(k)} with fixed damage \bar{\mathbf{a}}^{(k-1)}: \mathbf{K}_{uu}(\bar{\mathbf{a}}^{(k-1)}) \delta \mathbf{a} = \mathbf{r}_u(\mathbf{a}^{(k-1)}, \bar{\mathbf{a}}^{(k-1)}), set \mathbf{a}^{(k)} = \mathbf{a}^{(k-1)} + \delta \mathbf{a}.$ -\State $At element Gauss integration points, evaluate updated strains \boldsymbol{\epsilon}^{(k)} = \mathbf{B} \mathbf{a}^{(k)} and update history variable field: \mathcal{H}_{n+1}^{(k)} = \max(\mathcal{H}_n, \psi_0^+(\boldsymbol{\epsilon}^{(k)})).$ -\State $Solve damage sub-problem for \bar{\mathbf{a}}^{(k)} with fixed displacement \mathbf{a}^{(k)} and updated history \mathcal{H}_{n+1}^{(k)}: \mathbf{K}_{dd} \delta \bar{\mathbf{a}} = \bar{\mathbf{r}}_d(\mathbf{a}^{(k)}, \bar{\mathbf{a}}^{(k-1)}), set \bar{\mathbf{a}}^{(k)} = \bar{\mathbf{a}}^{(k-1)} + \delta \bar{\mathbf{a}}.$ -\If{$Over-relaxation acceleration is enabled.$} -\State $Apply over-relaxation update: \bar{\mathbf{a}}^{(k)} \leftarrow \omega_{rel} \bar{\mathbf{a}}^{(k)} + (1 - \omega_{rel}) \bar{\mathbf{a}}^{(k-1)} \text{ with } \omega_{rel} > 1.$ -\EndIf -\State $Increment iteration counter k \leftarrow k + 1.$ -\EndWhile -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Bourdin et al. (2000, 2008)_ - - -## 4. Known Pitfalls - -- **staggered-solver-extreme-computational-inefficiency**: Because the staggered scheme decouples displacement and damage into a non-linear Gauss-Seidel iteration, convergence becomes extremely slow during unstable crack initiation and rapid propagation increments. In complex boundary value problems, the staggered algorithm frequently requires over 1,000 iterations per increment to achieve residual convergence, resulting in CPU runtimes 3x to 7x longer than monolithic quasi-Newton (BFGS) solvers. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ -- **one-pass-staggered-energy-error-accumulation**: Using a one-pass (non-iterative) staggered scheme where displacement and damage sub-problems are solved only once per increment without checking global convergence can lead to severe energy conservation errors and artificial delay of crack propagation unless extremely small time steps (\Delta t < 10^{-5}) are used. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Molnar et al. (2020), An open-source Abaqus implementation of the phase-field method)_ -- **loose-tolerance-staggered-stagnation**: Setting loose convergence tolerances in the staggered inner loop causes premature termination before displacement and damage fields reach mutual equilibrium. This introduces artificial numerical toughening, incorrect crack branching trajectories, or non-physical residual stresses across localized damage zones. _(Source: Wu and Huang (2020), Comprehensive implementations of phase-field damage models in Abaqus; Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory)_ - -## References - -- Bourdin, B., Francfort, G. A., and Marigo, J.-J. (2000). Numerical experiments in revisited brittle fracture. Journal of the Mechanics and Physics of Solids, 48(4), 797-826. -- Bourdin, B., Francfort, G. A., and Marigo, J.-J. (2008). The variational approach to fracture. Journal of Elasticity, 91(1-3), 5-148. -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Wu, J.-Y., and Huang, Y. (2020). Comprehensive implementations of phase-field damage models in Abaqus. Theoretical and Applied Fracture Mechanics, 106, 102440. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Molnar, G., Gravouil, A., Seghir, R., and Réthoré, J. (2020). An open-source Abaqus implementation of the phase-field method to study the effect of plasticity on the instantaneous fracture toughness in dynamic crack propagation. Computer Methods in Applied Mechanics and Engineering, 365, 113004. -- Tao, Z., Li, X., Tao, S., and Chen, Z. (2022). Phase-field modeling of 3D fracture in elasto-plastic solids based on the shear-modified GTN model and Abaqus subroutines UEL/UMAT. Engineering Fracture Mechanics, 260, 108196. -- Alessi, R., Marigo, J.-J., Maurini, C., and Vidoli, S. (2018). Coupling damage and plasticity for a phase-field regularisation of brittle, cohesive and ductile fracture: One-dimensional examples. International Journal of Mechanical Sciences, 149, 559-576. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-thermomechanical.md b/packages/akms/src/akms/_bundled/global_nodes/pf-thermomechanical.md deleted file mode 100644 index 3580953..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-thermomechanical.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: pf-thermomechanical -title: Thermo-Mechanical Phase-Field Fracture -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- thermo-mechanical -- taylor-quinney -- gc-temperature -- miehe-2017 -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-ductile-plasticity-coupling - type: refines - weight: 0.7 -- to: thermal-coupled-mechanics - type: requires - weight: 1.0 -- to: thermal-softening - type: requires - weight: 1.0 -- to: pf-spectral-split - type: requires - weight: 1.0 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Thermo-Mechanical Phase-Field Fracture - -## Summary - -Thermodynamic formulation, governing balance laws, and numerical algorithms for coupled thermo-mechanical phase-field fracture mechanics. The continuum framework unifies non-linear thermo-elastoplasticity, thermal energy balance with Taylor-Quinney plastic work conversion, and diffusive phase-field crack propagation. Rather than modifying critical fracture toughness G_c via ad hoc temperature power laws, thermal failure is driven by temperature-dependent yield stress degradation (thermal softening) in combination with strain-rate effects and plastic work dissipation. Grounded in the foundational variational and multi-physics frameworks of Miehe et al. (2015 Part II), McAuliffe & Waisman (2015, 2016), Dittmann et al. (2020), and Li et al. (2025), the governing equations enforce heat generation from plastic dissipation \mathcal{D}_{int} = \chi \boldsymbol{\sigma} : \dot{\boldsymbol{\epsilon}}^p and degrade elastic stiffness and yield strength while resolving thermal shock, localized shear heating, and dynamic crack growth. - -## 1. Core Concept - -Coupling thermo-mechanics with phase-field fracture requires satisfying the first and second laws of thermodynamics across elastic deformation, plastic dissipation, thermal conduction, and surface energy creation. In high-strain-rate or dynamic thermal shock applications, mechanical plastic work generates heat localizing along narrow bands. The temperature rise \Delta T is governed by the heat conduction equation \rho_0 c_p \dot{T} = \kappa \Delta T + \chi \boldsymbol{\sigma} : \dot{\boldsymbol{\epsilon}}^p, where \chi \in [0.8, 1.0] is the Taylor-Quinney coefficient quantifying the fraction of inelastic work converted to heat. Thermal softening reduces the flow stress \sigma_y(T) = \sigma_0 \exp[-\delta(T - T_0)] or \sigma_0 [1 - ((T - T_0)/(T_m - T_0))^m], inducing thermal-plastic instabilities (such as adiabatic shear bands) that concentrate plastic dissipation and accelerate phase-field damage evolution d. The phase-field evolution equation is driven by the historical maximum positive elastic and plastic work densities, while heat generated by plastic work feeds back into thermal softening, capturing the complete transition from thermo-plastic necking to macroscopic thermal fracture. - -## 2. Mathematical Formulation - -**coupled_thermal_energy_balance** -$$ -\rho_0 c_p \dot{T} = \kappa J \Delta T + \chi \boldsymbol{\tau} : \dot{\boldsymbol{\epsilon}}^p + R -$$ -_Source: McAuliffe and Waisman (2015), A unified model for metal failure capturing shear banding and fracture; Li et al. (2025), Phase field fracture in elastoplastic solids; Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture_ - -**thermal_softening_yield_function** -$$ -\sigma_y(\epsilon^p, \dot{\epsilon}^p, T) = \sigma_0(\epsilon^p) \left[ 1 + C \ln\left(\frac{\dot{\epsilon}^p}{\dot{\epsilon}_0}\right) \right] \left[ 1 - \left(\frac{T - T_{room}}{T_{melt} - T_{room}}\right)^m \right] -$$ -_Source: Li et al. (2025), Phase field fracture in elastoplastic solids; McAuliffe and Waisman (2015), A unified model for metal failure capturing shear banding and fracture; Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II_ - -**exponential_thermal_softening_flow_stress** -$$ -y(T) = y_0 \exp\left(-\frac{T - T_0}{\eta_y}\right) -$$ -_Source: Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II. Coupled brittle-to-ductile failure criteria and crack propagation in thermo-elastic-plastic solids_ - -**thermo_mechanical_phase_field_driving_force** -$$ -\mathcal{H}_{n+1} = \max\left(\mathcal{H}_n, \psi_0^+ + \psi_0^{pl} - \psi_c\right), \quad g_c l_c \Delta d - \frac{g_c}{l_c} d + 2(1-d)\mathcal{H}_{n+1} = \varpi \dot{d} -$$ -_Source: Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II; Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture_ - -**Notation:** -d: scalar phase-field damage variable; T, T_0, T_{room}, T_{melt}: temperature, reference, room, and melting temperatures; \rho_0: reference mass density; c_p: specific heat capacity; \kappa: thermal conductivity; \chi: Taylor-Quinney inelastic heat conversion factor; \boldsymbol{\tau}, \boldsymbol{\sigma}: Kirchhoff and Cauchy stress tensors; \boldsymbol{\epsilon}^p, \dot{\boldsymbol{\epsilon}}^p: plastic strain and plastic strain rate; \sigma_y, y(T): temperature-degraded yield flow stress; m, \eta_y, \delta: thermal softening parameters; g_c: critical fracture energy; l_c: regularization length scale parameter; \mathcal{H}: historical maximum energy release rate driving field. - - -## 3. Algorithmic Implementation - -**staggered-thermo-mechanical-phase-field-solver** -$$ -\begin{algorithmic} -\State $Initialize displacement \mathbf{u}_0, velocity \dot{\mathbf{u}}_0, temperature T_0, equivalent plastic strain \alpha_0, phase field d_0 = 0, and history field \mathcal{H}_0 = 0.$ -\For{$Loop over time increments n = 0, 1, 2, \dots, N_{steps} with increment \Delta t.$} -\State $Solve mechanical momentum balance equation for displacement \mathbf{u}_{n+1} and trial Kirchhoff stress \boldsymbol{\tau}_{n+1}^{trial}.$ -\State $Perform plastic return-mapping incorporating thermal softening flow stress \sigma_y(\alpha_{n+1}, \dot{\alpha}_{n+1}, T_n) to compute updated stress \boldsymbol{\tau}_{n+1} and plastic strain increment \Delta \alpha_{n+1}.$ -\State $Evaluate Taylor-Quinney plastic dissipation heat source \dot{Q}_{thermal} = \chi \boldsymbol{\tau}_{n+1} : \frac{\Delta \boldsymbol{\epsilon}_{n+1}^p}{\Delta t} and solve heat conduction equation for updated temperature T_{n+1}.$ -\State $Update damage driving history field \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \psi_{0, n+1}^+ + \psi_{0, n+1}^{pl} - \psi_c).$ -\State $Solve phase-field evolution equation for d_{n+1}: \left( \frac{g_c}{l_c} + 2 \mathcal{H}_{n+1} + \frac{\varpi}{\Delta t} \right) d_{n+1} - g_c l_c \Delta d_{n+1} = 2 \mathcal{H}_{n+1} + \frac{\varpi}{\Delta t} d_n.$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II; McAuliffe and Waisman (2015), A unified model for metal failure capturing shear banding and fracture; Dittmann et al. (2020), Phase-field modeling of porous-ductile fracture_ - - -## 4. Known Pitfalls - -- **misattributing-thermal-fracture-to-gc-temperature-power-laws**: Assuming critical fracture toughness G_c is governed by an explicit temperature power law G_c(T) = G_{c0}(T/T_0)^n is unsupported by continuum mechanics literature. Thermal failure modes and thermo-plastic crack localization are driven by temperature degradation of material flow stress \sigma_y(T) (thermal softening) and plastic dissipation heat generation. _(Source: Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II; McAuliffe and Waisman (2015), A unified model for metal failure capturing shear banding and fracture; Li et al. (2025), Phase field fracture in elastoplastic solids)_ -- **neglecting-taylor-quinney-heat-generation-in-high-rate-fracture**: Omitting plastic dissipation heat generation (\chi = 0) in dynamic or high-strain-rate impact simulations prevents localized thermal softening near crack tips and notch fronts. This artificially suppresses shear band formation and leads to incorrect predictions of dynamic fracture initiation. _(Source: McAuliffe and Waisman (2015, 2016); Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II; Li et al. (2025), Phase field fracture in elastoplastic solids)_ -- **spurious-thermal-shock-oscillations-from-coarse-spatial-mesh**: In thermal shock fracture problems (e.g. rapid surface cooling), if the element size h exceeds l_c / 2 near steep thermal gradients, spatial phase-field approximation \nabla d becomes ill-conditioned, causing non-physical surface crack oscillations or mesh-aligned crack paths. _(Source: Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration; Miehe et al. (2015), Phase field modeling of fracture in multi-physics problems. Part II)_ - -## References - -- Miehe, C., Hofacker, M., Schänzel, L.-M., and Aldakheel, F. (2015). Phase field modeling of fracture in multi-physics problems. Part II. Coupled brittle-to-ductile failure criteria and crack propagation in thermo-elastic-plastic solids. Computer Methods in Applied Mechanics and Engineering, 294, 486-522. -- McAuliffe, C., and Waisman, H. (2015). A unified model for metal failure capturing shear banding and fracture. International Journal of Plasticity, 65, 131-151. -- McAuliffe, C., and Waisman, H. (2016). A coupled phase field shear band model for ductile–brittle transition in notched plate impacts. Computer Methods in Applied Mechanics and Engineering, 305, 173-195. -- Dittmann, M., Aldakheel, F., Schulte, J., Schmidt, F., Krüger, M., Wriggers, P., and Hesch, C. (2020). Phase-field modeling of porous-ductile fracture in non-linear thermo-elasto-plastic solids. Computer Methods in Applied Mechanics and Engineering, 361, 112730. -- Li, C., Liu, J., Dong, L., Wu, C., Steven, G., Li, Q., and Fang, J. (2025). Phase field fracture in elastoplastic solids: a stress-state, strain-rate, and orientation dependent model in explicit dynamics and its applications to additively manufactured metals. Journal of the Mechanics and Physics of Solids, 197, 105978. -- Wang, T., Ye, X., Liu, Z., Liu, X., Chu, D., and Zhuang, Z. (2020). A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration. Computational Mechanics, 65(5), 1305-1321. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-variational-griffith.md b/packages/akms/src/akms/_bundled/global_nodes/pf-variational-griffith.md deleted file mode 100644 index b913ed4..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-variational-griffith.md +++ /dev/null @@ -1,193 +0,0 @@ ---- -id: pf-variational-griffith -title: Griffith Energy & Variational Fracture (Francfort-Marigo) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- fracture -- griffith -- variational -- gamma-convergence -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: damage-continuum-framework - type: refines - weight: 0.7 -- to: pf-at2-regularization - type: feeds-into - weight: 0.5 -- to: pf-at1-regularization - type: feeds-into - weight: 0.5 -- to: pf-cohesive-zone - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Griffith Energy & Variational Fracture (Francfort-Marigo) - -## Summary -The variational formulation of fracture due to Francfort and Marigo (1998) -recasts Griffith's criterion as a global energy minimization: the elastic -strain energy plus the surface energy of the crack set is minimized over -admissible displacement fields and crack geometries. Unlike classical -Griffith, no pre-existing crack is required and crack nucleation, -branching, and arrest emerge naturally from the minimization. The -Ambrosio-Tortorelli regularization makes this tractable in FE codes by -smearing the crack into a phase field that Gamma-converges to the sharp -crack as the regularization length ell -> 0. - - -## 1. Core Concept -Griffith's classical theory states that a crack advances when the energy -release rate G equals the critical fracture energy Gc. This is a local -criterion that requires a pre-existing crack and knowledge of crack-tip -fields, and cannot predict crack nucleation, kinking, or branching from -first principles. - -Francfort and Marigo (1998) reformulated fracture as a global variational -principle: minimize the total energy - E(u, K) = elastic_energy(u) + Gc * H^{n-1}(K) -over admissible displacements u and crack sets K, subject to the -irreversibility constraint K(t1) subset K(t2) for t1 < t2. This admits -arbitrary crack topology evolution from minimization alone. - -Direct numerical solution is intractable because K is a lower-dimensional -set. The Ambrosio-Tortorelli (1990) regularization replaces the sharp -crack K with a continuous phase field d (or phi) in [0,1] (d=0 intact, -d=1 fully cracked) and approximates the surface energy by a volume -integral - Gc * H^{n-1}(K) approx Gc * integral_Omega gamma_l(d, grad d) dV -where gamma_l is a regularized crack surface density per unit volume. -As ell -> 0, the regularized functional Gamma-converges to the sharp-crack -Francfort-Marigo functional, guaranteeing the discrete approximation -recovers the variational fracture solution. - - -## 2. Mathematical Formulation -The phase-field formulation introduces a continuous order parameter -representing material damage and a crack surface density that approximates -the codimension-1 crack set in the limit ell -> 0. - - -**griffith-criterion:** - -$$ -G \;=\; -\frac{\partial \Pi}{\partial A} \;=\; G_c \quad \text{(crack advance condition)} -$$ - -where Pi = total potential energy; A = crack area; Gc = critical energy release rate - -**francfort-marigo-energy:** - -$$ -\mathcal{E}(\mathbf{u}, K) \;=\; \int_{\Omega \setminus K} \psi(\boldsymbol{\varepsilon}(\mathbf{u})) \, dV \;+\; G_c \, \mathcal{H}^{n-1}(K) -$$ - -where psi = elastic strain energy density; H^{n-1} = (n-1)-dimensional Hausdorff measure of crack set K - -**minimization-principle:** - -$$ -(\mathbf{u}_t, K_t) \;=\; \arg\min_{(\mathbf{u}, K)} \mathcal{E}(\mathbf{u}, K) \quad \text{s.t.} \quad K_s \subset K_t \;\forall s \le t -$$ - -where irreversibility: crack set monotonically grows in time - -**regularized-crack-density:** - -$$ -\gamma_\ell(d, \nabla d) \;=\; \frac{1}{2\ell} \, d^2 \;+\; \frac{\ell}{2} |\nabla d|^2 \quad \text{(AT2 form)} -$$ - -where ell = regularization length scale; gamma_l integrates to approx H^{n-1}(K) as ell -> 0 - -**regularized-energy:** - -$$ -\mathcal{E}_\ell(\mathbf{u}, d) \;=\; \int_\Omega g(d) \, \psi(\boldsymbol{\varepsilon}) \, dV \;+\; G_c \int_\Omega \gamma_\ell(d, \nabla d) \, dV -$$ - -where g(d) = degradation function (typically (1-d)^2); recovers Francfort-Marigo as ell -> 0 - -**gamma-convergence:** - -$$ -\mathcal{E}_\ell \;\xrightarrow{\Gamma}\; \mathcal{E} \quad \text{as} \quad \ell \to 0 -$$ - -where Gamma-convergence guarantees minimizers of the regularized functional approximate minimizers of the sharp-crack functional - -**Notation:** - -- $u$ — displacement field -- $d, phi$ — phase field / damage variable in [0,1] -- $K$ — sharp crack set (lower-dimensional) -- $Gc$ — critical fracture energy (Griffith) -- $ell$ — regularization length scale -- $gamma_l$ — regularized crack surface density per volume -- $g(d)$ — degradation function - - -## 3. Algorithmic Implementation -**Algorithm: variational-fracture-flow** - -$$ -\begin{algorithmic} -\State $$ -\State $$ -\State $$ -\State $$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Two ti.field arrays: u (vector) and d (scalar). At each time step, -assemble two residuals (momentum + phase-field balance) and solve -either alternately (staggered) or together (monolithic). History -variable kappa stored at Gauss points. - - - -## 4. Known Pitfalls -**ell-as-physical-length:** AT2 has no elastic limit (sigma_c -> 0 as ell -> 0), so ell is a -physical material length, not a vanishing numerical parameter. Choosing -ell affects the response, not just resolution. AT1 and PF-CZM -partially decouple ell from sigma_c. - - -**mesh-resolution:** Gamma-convergence requires h << ell; rule of thumb h <= ell/2 to -resolve the diffuse crack profile. Coarse meshes overestimate Gc by -a factor (1 + h/(c_w*ell)). - - -**irreversibility-enforcement:** Without explicit irreversibility, d can decrease on unloading, -producing unphysical "crack healing". Enforce via kappa-history -(Miehe 2010), penalty term, or active-set bound enforcement. - - -**nonconvex-energy:** The coupled (u, d) energy is non-convex in (u, d) jointly though -convex in each separately. Monolithic Newton can stall at local -minima; staggered alternate minimization is more robust but slower -to converge. - - -**branch-prediction-cost:** Variational fracture predicts branching automatically — but the -mesh must be fine enough to resolve all branches. Use AMR (h-adaptive -refinement) where d > threshold to keep cost tractable. - - -## 5. References -- Francfort, G. A., Marigo, J.-J. (1998). Revisiting brittle fracture as an energy minimization problem. JMPS 46:1319-1342. -- Bourdin, B., Francfort, G. A., Marigo, J.-J. (2000). Numerical experiments in revisited brittle fracture. JMPS 48:797-826. -- Ambrosio, L., Tortorelli, V. M. (1990). Approximation of functionals depending on jumps by elliptic functionals via Gamma-convergence. CPAM 43:999-1036. -- Miehe, C., Welschinger, F., Hofacker, M. (2010). Thermodynamically consistent phase-field models of fracture: variational principles and multi-field FE implementations. IJNME 83:1273-1311. -- Griffith, A. A. (1921). The phenomena of rupture and flow in solids. Philosophical Transactions A 221:163-198. diff --git a/packages/akms/src/akms/_bundled/global_nodes/pf-voldev-split.md b/packages/akms/src/akms/_bundled/global_nodes/pf-voldev-split.md deleted file mode 100644 index ffdd47b..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/pf-voldev-split.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -id: pf-voldev-split -title: Volumetric-Deviatoric Energy Split (Amor) -domain: computational-mechanics -subdomain: phase-field-fracture -tags: -- phase-field -- voldev-split -- amor -- energy-decomposition -status: established -confidence: 0.9 -source: hybrid -edges: -- to: pf-at2-regularization - type: feeds-into - weight: 0.5 -- to: pf-spectral-split - type: contradicts - weight: 0.0 -- to: pf-energy-split-comparison - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Volumetric-Deviatoric Energy Split (Amor) - -## Summary - -Formulation, physical behavior, and numerical implementation of the Volumetric-Deviatoric strain energy decomposition (Amor et al., 2009; Zhang et al., 2022) in phase-field fracture mechanics. The volumetric-deviatoric split partitions undamaged elastic strain energy density \psi_0(\boldsymbol{\epsilon}) into a positive crack-driving component \psi^+ (degraded by (1-d)^2) and a non-driving compressive component \psi^- (undegraded). The split isolates volumetric expansion \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+ and deviatoric strain energy \boldsymbol{\epsilon}_{dev} : \boldsymbol{\epsilon}_{dev} to drive damage evolution while protecting compressive volumetric states \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_- from degradation. Benchmark evaluations (Zhang et al., 2022) demonstrate that volumetric-deviatoric splits accurately predict shear failure and local shear strain distributions under pure shear loading without the artificial stress overestimation seen in spectral splits. Claims of a 3x-5x speedup per Gauss point over spectral splits are misattributed; documented 3x-7x computational speedups in phase-field literature arise from global solver selection (monolithic BFGS vs. staggered solvers), not local energy decomposition. - -## 1. Core Concept - -The volumetric-deviatoric energy decomposition proposed by Amor et al. (2009) addresses unilateral crack contact by separating elastic strain energy into spherical (volumetric) and deviatoric (shear) parts. Unlike isotropic models that degrade total strain energy—causing spurious cracking under hydrostatic compression—the volumetric-deviatoric split degrades only the positive (tensile) volumetric strain energy \frac{1}{2} K_n \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+^2 and the full deviatoric strain energy \mu (\boldsymbol{\epsilon}_{dev} : \boldsymbol{\epsilon}_{dev}). Compressive volumetric energy \frac{1}{2} K_n \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_-^2 remains undegraded, preventing crack initiation under pure hydrostatic compression. Under pure shear or shear-dominated loading, volumetric-deviatoric splits (StrainDe and StressDe) allow full deviatoric energy to drive crack propagation, enabling realistic shear band localization (Zhang et al., 2022). However, under combined compressive-shear states, un-degraded compressive protection applies only to the hydrostatic trace, so deviatoric strains can still accumulate damage unless pressure-dependent thresholds or multi-field modifications are applied. Local evaluation of the volumetric-deviatoric split is computationally simple and closed-form, but overall solver efficiency is governed by the global non-linear solver (BFGS quasi-Newton vs. staggered alternate minimization). - -## 2. Mathematical Formulation - -**volumetric_deviatoric_energy_split** -$$ -\psi^+(\boldsymbol{\epsilon}) = \frac{1}{2} K_n \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+^2 + \mu (\boldsymbol{\epsilon}_{dev} : \boldsymbol{\epsilon}_{dev}), \quad \psi^-(\boldsymbol{\epsilon}) = \frac{1}{2} K_n \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_-^2 -$$ -_Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods for phase field fracture models; Amor et al. (2009), Regularized formulation of the variational brittle fracture; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture_ - -**volumetric_deviatoric_degraded_stress** -$$ -\boldsymbol{\sigma} = [(1-d)^2 + k] \left( K_n \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_+ \mathbf{I} + 2\mu \boldsymbol{\epsilon}_{dev} \right) + K_n \langle \text{tr}(\boldsymbol{\epsilon}) \rangle_- \mathbf{I} -$$ -_Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture_ - -**stress_based_volumetric_deviatoric_variant** -$$ -\boldsymbol{\sigma}_0 = -p \mathbf{I} + \mathbf{s}, \quad \psi^+ = \frac{1}{2 K_3} \langle -p \rangle_+^2 + \frac{1}{4\mu} (\mathbf{s} : \mathbf{s}), \quad \psi^- = \frac{1}{2 K_3} \langle -p \rangle_-^2 -$$ -_Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods; Zhang et al. (2023), Phase-field modeling of coupled spall and adiabatic shear banding_ - -**Notation:** -\boldsymbol{\epsilon}: small strain tensor; \boldsymbol{\epsilon}_{dev}: deviatoric strain tensor; \mathbf{I}: second-order identity tensor; \boldsymbol{\sigma}: degraded Cauchy stress tensor; \boldsymbol{\sigma}_0: undamaged Cauchy stress tensor; \mathbf{s}: deviatoric Cauchy stress tensor; p: hydrostatic pressure; K_n: n-dimensional bulk modulus; \lambda, \mu: Lamé elastic constants; d: scalar phase-field damage variable (d \in [1]); k: residual stiffness parameter; \psi^+, \psi^-: positive (tensile/shear driving) and negative (compressive non-driving) strain energy density components; \mathcal{H}: historical maximum energy release rate field. - - -## 3. Algorithmic Implementation - -**volumetric-deviatoric-split-constitutive-update** -$$ -\begin{algorithmic} -\State $At finite element integration point, receive trial total strain tensor \boldsymbol{\epsilon}_{n+1}.$ -\State $Compute volumetric strain \text{tr}(\boldsymbol{\epsilon}_{n+1}) and Macaulay brackets \langle \text{tr}(\boldsymbol{\epsilon}_{n+1}) \rangle_+ and \langle \text{tr}(\boldsymbol{\epsilon}_{n+1}) \rangle_-.$ -\State $Compute deviatoric strain tensor: \boldsymbol{\epsilon}_{dev} = \boldsymbol{\epsilon}_{n+1} - \frac{1}{n}\text{tr}(\boldsymbol{\epsilon}_{n+1})\mathbf{I}.$ -\State $Evaluate positive tensile and shear strain energy density: \psi^+ = \frac{1}{2} K_n \langle \text{tr}(\boldsymbol{\epsilon}_{n+1}) \rangle_+^2 + \mu (\boldsymbol{\epsilon}_{dev} : \boldsymbol{\epsilon}_{dev}).$ -\State $Update damage history field enforcing irreversibility \dot{d} \ge 0: \mathcal{H}_{n+1} = \max(\mathcal{H}_n, \psi^+).$ -\State $Evaluate degraded Cauchy stress tensor: \boldsymbol{\sigma}_{n+1} = [(1-d_{n+1})^2 + k] \left( K_n \langle \text{tr}(\boldsymbol{\epsilon}_{n+1}) \rangle_+ \mathbf{I} + 2\mu \boldsymbol{\epsilon}_{dev} \right) + K_n \langle \text{tr}(\boldsymbol{\epsilon}_{n+1}) \rangle_- \mathbf{I}.$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods; Wang et al. (2020), A phase-field model of thermo-elastic coupled brittle fracture; Amor et al. (2009)_ - - -## 4. Known Pitfalls - -- **spurious-damage-under-pure-compression-with-deviatoric-strains**: The volumetric-deviatoric strain energy split degrades the entire deviatoric strain energy \mu(\boldsymbol{\epsilon}_{dev} : \boldsymbol{\epsilon}_{dev}). In pure hydrostatic compression without shear, no damage develops. However, under high compressive shear where negative volumetric strain is present along with deviatoric strain, \psi^+ accumulates deviatoric energy, potentially causing spurious damage growth under compressive confinement. _(Source: Zhang et al. (2022), Assessment of four strain energy decomposition methods for phase field fracture models; Miehe et al. (2010), Thermodynamically consistent phase-field models of fracture)_ -- **misattributing-3x-5x-speedup-to-volumetric-deviatoric-split**: Attributing a 3x-5x computational speedup per Gauss point to the volumetric-deviatoric split over spectral decomposition is incorrect. Literature benchmarks show that local closed-form volumetric-deviatoric calculations add negligible runtime differences compared to 3x3 spectral Eigendecompositions; the documented 3x-7x speedups stem from global solver selection (monolithic BFGS vs. staggered solvers). _(Source: Wu et al. (2020), On the BFGS monolithic algorithm for the unified phase field damage theory; Zhang et al. (2022), Assessment of four strain energy decomposition methods)_ - -## References - -- Amor, H., Marigo, J.-J., and Maurini, C. (2009). Regularized formulation of the variational brittle fracture with unilateral contact: Numerical experiments. Journal of the Mechanics and Physics of Solids, 57(8), 1209-1229. -- Zhang, S., Jiang, W., and Tonks, M. R. (2022). Assessment of four strain energy decomposition methods for phase field fracture models using quasi-static and dynamic benchmark cases. Materials Theory, 6, 6. -- Miehe, C., Hofacker, M., and Welschinger, F. (2010). Thermodynamically consistent phase-field models of fracture: Variational principles and multi-field FE implementations. International Journal for Numerical Methods in Engineering, 83(10), 1273-1311. -- Wang, T., Ye, X., Liu, Z., Liu, X., Chu, D., and Zhuang, Z. (2020). A phase-field model of thermo-elastic coupled brittle fracture with explicit time integration. Computational Mechanics, 65(5), 1305-1321. -- Wu, J.-Y., Huang, Y., and Nguyen, V. P. (2020). On the BFGS monolithic algorithm for the unified phase field damage theory. Computer Methods in Applied Mechanics and Engineering, 360, 112704. -- Zhang, H., Peng, H., Pei, X.-Y., Wu, J.-Y., Li, P., Tang, T.-G., Cai, L.-C., Li, Y., and Liu, H. (2023). Phase-field modeling of coupled spall and adiabatic shear banding and simulation of complex cracks in ductile metals. Journal of the Mechanics and Physics of Solids, 172, 105186. diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-consistent-tangent-general.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-consistent-tangent-general.md deleted file mode 100644 index ec3e0ac..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-consistent-tangent-general.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: plasticity-consistent-tangent-general -title: Consistent Tangent for General Models -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- consistent-tangent -- jacobian -- algorithmic-tangent -- verification -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-general-return-mapping - type: requires - weight: 1.0 -- to: plasticity-cpp-nonassociative - type: requires - weight: 0.9 -- to: plasticity-consistent-tangent-j2 - type: refines - weight: 1.0 -- to: fem-newton-raphson - type: feeds-into - weight: 1.0 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Consistent Tangent for General Models - -## Summary - -The consistent algorithmic tangent operator for general elastoplastic constitutive models is derived by exact linearization of the discrete implicit return-mapping algorithm, ensuring asymptotic quadratic convergence in global Newton-Raphson solvers. - -## 1. Core Concept - -The consistent algorithmic tangent operator provides the exact derivative of the updated stress tensor with respect to the strain increment at the end of a time step, \mathbf{D}^{\mathrm{alg}} = d\bm{\sigma}_{n+1} / d\bm{\varepsilon}_{n+1}. Unlike the continuum elastoplastic tangent tensor \mathbf{D}^{\mathrm{ep}}, which is derived from rate equations assuming instantaneous yield surface consistency, the consistent tangent operator accounts for the discrete algorithmic step size \Delta \gamma and local iteration history. As established by Simo and Hughes (1998) and Borst and Crisfield (2012), exact linearization of backward Euler closest-point projection algorithms yields an algorithmic flexibility tensor \mathbf{\Xi}_{n+1} = [\mathbf{C}^{-1} + \Delta \gamma \partial^2 f / \partial \bm{\sigma}^2]^{-1}. Using the algorithmic tangent tensor in implicit finite element formulations restores the asymptotic quadratic convergence rate of the global Newton-Raphson iteration. - -## 2. Mathematical Formulation - -**Algorithmic Stress Linearization** -$$ -d\bm{\sigma}_{n+1} = \mathbf{\Xi}_{n+1} : \left( d\bm{\varepsilon}_{n+1} - d\gamma_{n+1} \frac{\partial g}{\partial \bm{\sigma}_{n+1}} \right) -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 147, 213; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 252_ - -**General Algorithmic Consistent Tangent Tensor** -$$ -\mathbf{D}^{\mathrm{alg}} = \mathbf{\Xi}_{n+1} - \frac{\left( \mathbf{\Xi}_{n+1} : \frac{\partial g}{\partial \bm{\sigma}_{n+1}} \right) \otimes \left( \frac{\partial f}{\partial \bm{\sigma}_{n+1}} : \mathbf{\Xi}_{n+1} \right)}{\frac{\partial f}{\partial \bm{\sigma}_{n+1}} : \mathbf{\Xi}_{n+1} : \frac{\partial g}{\partial \bm{\sigma}_{n+1}} + H_{\mathrm{alg}}} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 147, 213; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 252_ - -**Discrete Plastic Multiplier Increment Linearization** -$$ -d\gamma_{n+1} = \frac{\frac{\partial f}{\partial \bm{\sigma}_{n+1}} : \mathbf{\Xi}_{n+1} : d\bm{\varepsilon}_{n+1}}{\frac{\partial f}{\partial \bm{\sigma}_{n+1}} : \mathbf{\Xi}_{n+1} : \frac{\partial g}{\partial \bm{\sigma}_{n+1}} + H_{\mathrm{alg}}} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 147, 213_ - -**Asymmetric Algorithmic Tangent Operator Structure** -$$ -\mathbf{D}^{\mathrm{alg}} = \mathbf{A}^{-1} : \mathbf{D}^e - \frac{\left( \mathbf{A}^{-1} : \mathbf{D}^e : \mathbf{n} \right) \otimes \left( \mathbf{n}^T : \mathbf{A}^{-1} : \mathbf{D}^e \right)}{\mathbf{n}^T : \mathbf{A}^{-1} : \mathbf{D}^e : \mathbf{n} + H} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.7, p. 252_ - -**Notation:** -\mathbf{D}^{\mathrm{alg}}: fourth-order consistent algorithmic tangent tensor; \mathbf{D}^e: fourth-order elastic stiffness tensor; \mathbf{C}: elasticity tensor (\mathbf{D}^e); \mathbf{\Xi}_{n+1}: modified algorithmic elasticity tensor; f: yield function; g: plastic potential function; \mathbf{n}: yield surface normal vector (\partial f / \partial \bm{\sigma}); \mathbf{m}: plastic flow direction vector (\partial g / \partial \bm{\sigma}); \Delta \gamma: discrete plastic multiplier; H, H_{\mathrm{alg}}: plastic hardening parameter. - - -## 3. Algorithmic Implementation - -**General Consistent Algorithmic Tangent Construction Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given converged local state at } t_{n+1}\text{: Cauchy stress } \bm{\sigma}_{n+1}, \text{ plastic multiplier } \Delta \gamma, \text{ internal hardening } \bm{q}_{n+1}, \text{ and elasticity tensor } \mathbf{C}$ -\State $\text{Compute yield surface gradient } \mathbf{n}_{n+1} = \frac{\partial f}{\partial \bm{\sigma}_{n+1}} \text{ and plastic potential gradient } \mathbf{m}_{n+1} = \frac{\partial g}{\partial \bm{\sigma}_{n+1}}$ -\State $\text{Compute second derivatives } \mathbf{H}_g = \frac{\partial^2 g}{\partial \bm{\sigma}_{n+1}^2} \text{ and hardening derivatives } \frac{\partial f}{\partial \bm{q}_{n+1}}, \frac{\partial \bm{q}_{n+1}}{\partial \Delta \gamma}$ -\State $\text{Form matrix } \mathbf{A} = \mathbf{I} + \Delta \gamma \mathbf{C} : \mathbf{H}_g$ -\State $\text{Invert } \mathbf{A} \text{ to evaluate modified algorithmic elasticity tensor } \mathbf{\Xi}_{n+1} = \mathbf{A}^{-1} : \mathbf{C}$ -\State $\text{Compute scalar denominator } d_{denom} = \mathbf{n}_{n+1} : \mathbf{\Xi}_{n+1} : \mathbf{m}_{n+1} + H_{\mathrm{alg}}$ -\State $\mathbf{D}^{\mathrm{alg}} = \mathbf{\Xi}_{n+1} - \frac{(\mathbf{\Xi}_{n+1} : \mathbf{m}_{n+1}) \otimes (\mathbf{n}_{n+1} : \mathbf{\Xi}_{n+1})}{d_{denom}}$ -\Return $\text{Return explicit fourth-order consistent algorithmic tangent tensor } \mathbf{D}^{\mathrm{alg}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 147, 213; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.7, p. 252_ - - -## 4. Known Pitfalls - -- **Loss of Quadratic Global Newton Convergence using Continuum Tangent**: Substituting the continuum elastoplastic tangent D^{ep} for the algorithmic consistent tangent D^{alg} in implicit global Newton-Raphson solvers degrades the quadratic convergence rate to linear, significantly increasing iteration counts per load step. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 122, 145; Kim_FEA for Elastoplastic Problems.pdf p. 195, 207; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 600)_ -- **Spurious Non-Symmetry Enforcement in Symmetric Global Solvers**: Enforcing major symmetry on D^{alg} when using non-associated flow rules (g \neq f) or non-linear kinematic hardening destroys exact linearization, preventing quadratic convergence in symmetric linear system solvers. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.7, p. 252; Simo_Hughes_1998_Computational inelasticity.pdf p. 147)_ -- **Singularity in Algorithmic Elasticity Tensor Inversion at Yield Vertices**: Attempting to evaluate smooth second-order derivatives \partial^2 g / \partial \bm{\sigma}^2 at non-smooth yield surface corners (e.g. Tresca, Mohr-Coulomb apices) causes matrix singular ill-conditioning unless multi-surface Koiter return mapping or subdifferential operators are applied. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 212-214; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 252; Simplify_radial_return_Part_1.pdf p. 1-2)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- Simplify_radial_return_Part_1.pdf -- Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-consistent-tangent-j2.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-consistent-tangent-j2.md deleted file mode 100644 index 599e084..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-consistent-tangent-j2.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: plasticity-consistent-tangent-j2 -title: Consistent Tangent for J2 Plasticity -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- consistent-tangent -- j2 -- newton -- algorithmic-tangent -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-radial-return - type: requires - weight: 1.0 -- to: plasticity-von-mises - type: requires - weight: 1.0 -- to: plasticity-consistent-tangent-general - type: refines - weight: 1.0 -- to: fem-newton-raphson - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Consistent Tangent for J2 Plasticity - -## Summary - -The consistent algorithmic tangent operator for J2 von Mises plasticity exacts the derivative of the stress update with respect to strain increments, preserving quadratic Newton-Raphson convergence. - -## 1. Core Concept - -In non-linear finite element analysis using implicit time integration, solving global equilibrium via Newton-Raphson iterations requires linearizing the residual force vector. For classical J2 von Mises plasticity integrated using the radial return algorithm (backward Euler), differentiating the discrete stress update with respect to the strain increment produces the exact consistent algorithmic tangent operator \mathbf{D}^{\mathrm{alg}}. While the continuum elastoplastic tangent tensor \mathbf{D}^{\mathrm{ep}} represents the instantaneous rate response on the yield surface, \mathbf{D}^{\mathrm{alg}} incorporates the discrete radial return projection scale factor \theta = 1 - 2\mu\Delta \gamma / \|\bm{s}^{\mathrm{tr}}\|. Substituting \mathbf{D}^{\mathrm{alg}} for \mathbf{D}^{\mathrm{ep}} in global stiffness matrices ensures asymptotic quadratic convergence in implicit FE solvers. - -## 2. Mathematical Formulation - -**J2 Algorithmic Consistent Tangent Tensor** -$$ -\mathbf{D}^{\mathrm{alg}} = K \mathbf{I} \otimes \mathbf{I} + 2\mu \theta_{n+1} \left( \mathbf{I}_{\mathrm{dev}} - \mathbf{n}_{n+1} \otimes \mathbf{n}_{n+1} \right) + 2\mu \left( \theta_{n+1} - \bar{\theta}_{n+1} \right) \mathbf{n}_{n+1} \otimes \mathbf{n}_{n+1} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 124; Kim_FEA for Elastoplastic Problems.pdf p. 202-205; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 35_ - -**Algorithmic Shear Reduction Factors** -$$ -\theta_{n+1} = 1 - \frac{2\mu \Delta \gamma}{\|\bm{\xi}^{\mathrm{tr}}_{n+1}\|}, \quad \bar{\theta}_{n+1} = \frac{1}{1 + \frac{H + K^{\prime}}{3\mu}} - (1 - \theta_{n+1}) -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 124; Kim_FEA for Elastoplastic Problems.pdf p. 202-204_ - -**Explicit Matrix Representation of J2 Tangent Modulus** -$$ -\mathbf{D}^{\mathrm{alg}} = \mathbf{D}^e - (c_1 - c_2) \mathbf{N} \otimes \mathbf{N} - c_2 \mathbf{I}_{\mathrm{dev}}, \quad c_1 = \frac{4\mu^2}{2\mu + \frac{2}{3}H}, \quad c_2 = \frac{4\mu^2 \Delta \gamma}{\|\bm{\eta}^{\mathrm{tr}}\|} -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 204, 209_ - -**Continuum versus Algorithmic Tangent Comparison** -$$ -\mathbf{D}^{\mathrm{ep}} = \lim_{\Delta \gamma \to 0} \mathbf{D}^{\mathrm{alg}} = \mathbf{D}^e - \frac{4\mu^2}{2\mu + \frac{2}{3}H} \mathbf{N} \otimes \mathbf{N} -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 189, 202; Simo_Hughes_1998_Computational inelasticity.pdf p. 124_ - -**Notation:** -\mathbf{D}^{\mathrm{alg}}: fourth-order consistent algorithmic tangent tensor; \mathbf{D}^{\mathrm{ep}}: fourth-order continuum elastoplastic tangent tensor; \mathbf{D}^e: elastic stiffness tensor; K: elastic bulk modulus; \mu: elastic shear modulus; \theta_{n+1}, \bar{\theta}_{n+1}: algorithmic shear scaling coefficients; \mathbf{n}_{n+1}, \mathbf{N}: unit yield surface normal tensor; \mathbf{I}_{\mathrm{dev}}: fourth-order deviatoric identity tensor; \Delta \gamma: discrete plastic consistency parameter increment; \|\bm{\xi}^{\mathrm{tr}}\|, \|\bm{\eta}^{\mathrm{tr}}\|: trial shifted deviatoric stress norm; H, K^{\prime}: kinematic and isotropic hardening moduli. - - -## 3. Algorithmic Implementation - -**J2 Algorithmic Consistent Tangent Evaluation Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given trial stress } \bm{s}^{\mathrm{tr}}, \text{ plastic strain increment } \Delta \gamma, \text{ elastic shear modulus } \mu, \text{ bulk modulus } K, \text{ and hardening moduli } H, K^{\prime}$ -\If{$\text{State is elastic } (\Delta \gamma = 0)$} -\State $\mathbf{D}^{\mathrm{alg}} = \mathbf{D}^e = K \mathbf{I} \otimes \mathbf{I} + 2\mu \mathbf{I}_{\mathrm{dev}}$ -\Return $\text{Return elastic tangent tensor } \mathbf{D}^e$ -\Else -\State $\bar{\theta}_{n+1} = \frac{1}{1 + \frac{H + K^{\prime}}{3\mu}} - (1 - \theta_{n+1})$ -\State $c_1 = \frac{4\mu^2}{2\mu + \frac{2}{3}(H + K^{\prime})}, \quad c_2 = \frac{4\mu^2 \Delta \gamma}{\|\bm{s}^{\mathrm{tr}}\|}$ -\State $\mathbf{D}^{\mathrm{alg}} = \mathbf{D}^e - (c_1 - c_2) \mathbf{n} \otimes \mathbf{n} - c_2 \mathbf{I}_{\mathrm{dev}}$ -\EndIf -\Return $\text{Return exact J2 consistent algorithmic tangent tensor } \mathbf{D}^{\mathrm{alg}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 124-125; Kim_FEA for Elastoplastic Problems.pdf p. 202-205, 209_ - - -## 4. Known Pitfalls - -- **Loss of Quadratic Newton-Raphson Convergence with Continuum Tangent**: Using the continuum elastoplastic tangent operator D^{ep} instead of the exact algorithmic consistent tangent operator D^{alg} in implicit FE solvers destroys quadratic Newton-Raphson convergence, resulting in linear convergence and excessive iteration counts. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 122; Kim_FEA for Elastoplastic Problems.pdf p. 189, 202; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 38)_ -- **Division by Zero at Zero Trial Deviatoric Stress Norm**: Evaluating the unit normal vector n = s^{tr} / \|s^{tr}\| or shear scale factor c_2 = 4\mu^2 \Delta \gamma / \|s^{tr}\| when the trial deviatoric stress vanishes (\|s^{tr}\| \to 0) causes floating-point division by zero; elastic handling must be enforced. _(Source: Kim_FEA for Elastoplastic Problems.pdf p. 202-204; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 34-35)_ -- **Spurious Non-Symmetry from Non-Linear Hardening Terms**: Omitting hardening derivatives in \bar{\theta}_{n+1} or incorrectly linearizing non-linear isotropic/kinematic hardening functions leads to inconsistent global Jacobians and loss of quadratic convergence. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 122-124; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 251-252)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-cpp-nonassociative.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-cpp-nonassociative.md deleted file mode 100644 index 869985d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-cpp-nonassociative.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: plasticity-cpp-nonassociative -title: Closest Point Projection for Non-J2 Surfaces -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- closest-point-projection -- non-associative -- drucker-prager -- multi-surface -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-general-return-mapping - type: refines - weight: 1.0 -- to: plasticity-drucker-prager - type: feeds-into - weight: 1.0 -- to: plasticity-hill48 - type: feeds-into - weight: 0.8 -- to: damage-gtn-yield-function - type: feeds-into - weight: 0.8 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Closest Point Projection for Non-J2 Surfaces - -## Summary - -The closest point projection algorithm for general non-J2 and non-associative yield surfaces solves the discrete backward Euler return-mapping system by enforcing plastic yield consistency alongside non-associated plastic flow rules. - -## 1. Core Concept - -The Closest Point Projection (CPP) algorithm for general non-J2 and non-associative yield criteria integrates elastoplastic constitutive equations over finite strain increments. When plastic flow direction \bm{m} = \partial g / \partial \bm{\sigma} differs from yield surface normal \bm{n} = \partial f / \partial \bm{\sigma} (such as in pressure-dependent Drucker-Prager or Mohr-Coulomb models where dilatancy angle \psi is smaller than friction angle \phi), trial elastic stress states \bm{\sigma}^{\mathrm{tr}} lie outside the admissible yield surface. The algorithm computes updated stress \bm{\sigma}_{n+1} and discrete plastic multiplier \Delta \gamma by iteratively solving a system of nonlinear residual equations using Newton-Raphson iterations with exact algorithmic Hessian matrices. - -## 2. Mathematical Formulation - -**Discrete Backward Euler Stress Update with Non-Associative Flow** -$$ -\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}} - \Delta \gamma \mathbf{D}^e : \mathbf{m}_{n+1}, \quad \mathbf{m}_{n+1} = \left. \frac{\partial g}{\partial \bm{\sigma}} \right|_{n+1} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 143-145; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 251-252_ - -**Non-Associative Flow Potential for Drucker-Prager Plasticity** -$$ -g(\bm{\sigma}) = \sqrt{J_2} + \alpha_g I_1 - k_g, \quad \alpha_g = \frac{2 \sin\psi}{\sqrt{3}(3 - \sin\psi)} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 228-232; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598_ - -**Local Newton Residual System for General CPP** -$$ -\bm{R}(\bm{\sigma}_{n+1}, \Delta \gamma) = \begin{bmatrix} \mathbf{D}^{e-1} : (\bm{\sigma}_{n+1} - \bm{\sigma}^{\mathrm{tr}}) + \Delta \gamma \mathbf{m}_{n+1} \\ f(\bm{\sigma}_{n+1}, \bm{q}_{n+1}) \end{bmatrix} = \bm{0} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.5, p. 146; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 251-252_ - -**Non-Symmetric Algorithmic Hessian Tensor** -$$ -\mathbf{\Xi}_{n+1} = \left[ \mathbf{D}^{e-1} + \Delta \gamma \frac{\partial^2 g}{\partial \bm{\sigma}_{n+1}^2} \right]^{-1} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 144, 213; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 252_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; \bm{\sigma}^{\mathrm{tr}}: trial elastic stress tensor; \mathbf{D}^e: fourth-order elastic stiffness tensor; \Delta \gamma: discrete plastic consistency multiplier; f: yield function; g: plastic potential function; \mathbf{n}: yield surface normal tensor (\partial f / \partial \bm{\sigma}); \mathbf{m}: plastic flow direction tensor (\partial g / \partial \bm{\sigma}); \psi: dilatancy angle; \phi: friction angle; \mathbf{\Xi}: modified algorithmic elasticity matrix; \bm{R}: local Newton residual vector. - - -## 3. Algorithmic Implementation - -**Non-Associative Closest Point Projection Return-Mapping Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: stress } \bm{\sigma}_n, \text{ internal variables } \bm{q}_n, \text{ and strain increment } \Delta \bm{\varepsilon}$ -\State $\bm{\sigma}^{\mathrm{tr}} = \bm{\sigma}_n + \mathbf{D}^e : \Delta \bm{\varepsilon}, \quad \bm{q}^{\mathrm{tr}} = \bm{q}_n, \quad f^{\mathrm{tr}} = f(\bm{\sigma}^{\mathrm{tr}}, \bm{q}^{\mathrm{tr}})$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}}, \quad \bm{q}_{n+1} = \bm{q}^{\mathrm{tr}}, \quad \bm{\varepsilon}^p_{n+1} = \bm{\varepsilon}^p_n$ -\Return $\text{Step is elastic; return trial state}$ -\Else -\EndIf -\While{$\|\bm{R}_{\bm{\sigma}}^{(k)}\| > \text{TOL}_1 \quad \text{or} \quad |f^{(k)}| > \text{TOL}_2$} -\State $\mathbf{n}^{(k)} = \left.\frac{\partial f}{\partial \bm{\sigma}}\right|_{n+1}^{(k)}, \quad \mathbf{m}^{(k)} = \left.\frac{\partial g}{\partial \bm{\sigma}}\right|_{n+1}^{(k)}, \quad \mathbf{H}_g^{(k)} = \left.\frac{\partial^2 g}{\partial \bm{\sigma}^2}\right|_{n+1}^{(k)}$ -\State $\mathbf{\Xi}^{(k)} = \left[ \mathbf{D}^{e-1} + \Delta \gamma^{(k)} \mathbf{H}_g^{(k)} \right]^{-1}$ -\State $d\Delta \gamma = \frac{f^{(k)} - \mathbf{n}^{(k)} : \mathbf{\Xi}^{(k)} : \bm{R}_{\bm{\sigma}}^{(k)}}{\mathbf{n}^{(k)} : \mathbf{\Xi}^{(k)} : \mathbf{m}^{(k)} + H_{\mathrm{alg}}^{(k)}}$ -\State $d\bm{\sigma} = -\mathbf{\Xi}^{(k)} : \left[ \bm{R}_{\bm{\sigma}}^{(k)} + d\Delta \gamma \mathbf{m}^{(k)} \right]$ -\State $\bm{\sigma}_{n+1}^{(k+1)} = \bm{\sigma}_{n+1}^{(k)} + d\bm{\sigma}, \quad \Delta \gamma^{(k+1)} = \Delta \gamma^{(k)} + d\Delta \gamma$ -\State $k = k + 1$ -\EndWhile -\State $\bm{\varepsilon}^p_{n+1} = \bm{\varepsilon}^p_n + \Delta \gamma \mathbf{m}_{n+1}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ plastic strain } \bm{\varepsilon}^p_{n+1}, \text{ and internal variables } \bm{q}_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.5, p. 146; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.7, p. 252_ - - -## 4. Known Pitfalls - -- **Loss of Symmetry in Algorithmic Tangent for Non-Associative Flow**: When plastic potential g differs from yield function f (e.g. \psi < \phi in frictional materials), the linearized algorithmic tangent tensor D^{alg} is non-symmetric; forcing a symmetric global solver discards off-diagonal terms, degrading Newton-Raphson convergence. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.7, p. 251-252; Simo_Hughes_1998_Computational inelasticity.pdf p. 147)_ -- **Singular Hessian Inversion at Non-Smooth Yield Surface Corners**: Evaluating second derivatives \partial^2 g / \partial \bm{\sigma}^2 at non-smooth singular points (such as the apex or edges of Drucker-Prager or Mohr-Coulomb surfaces) causes division by zero and ill-conditioning unless subdifferential multi-surface or apex return mapping algorithms are used. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 212-215; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598; Simplify_radial_return_Part_1.pdf p. 1-2)_ -- **Spurious Plastic Volume Expansion under Frictional Compression**: Assuming associative plastic flow (g = f) in pressure-dependent soil, concrete, or rock plasticity overpredicts volumetric plastic expansion (dilatancy); non-associated flow rules with independent dilatancy angles \psi < \phi are required to accurately model volumetric compaction. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 231-232; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- Simplify_radial_return_Part_1.pdf -- Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-cutting-plane.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-cutting-plane.md deleted file mode 100644 index c838e6a..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-cutting-plane.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: plasticity-cutting-plane -title: Cutting Plane Algorithm -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- cutting-plane -- return-mapping -- semi-implicit -- continuum-tangent -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-general-return-mapping - type: contradicts - weight: 0.7 -- to: plasticity-cpp-nonassociative - type: contradicts - weight: 0.7 -- to: constit-stress-update-architecture - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Cutting Plane Algorithm - -## Summary - -The cutting plane algorithm is an iterative return-mapping scheme that linearizes the yield function locally at each iteration step to compute plastic multiplier increments without requiring second derivatives or matrix inversions. - -## 1. Core Concept - -The cutting plane algorithm provides a simplified, computationally efficient alternative to the closest point projection (CPP) method for elastoplastic constitutive return mapping. First formulated by Simo and Ortiz (1987) and presented in Simo and Hughes (1998), the algorithm linearizes the yield criterion f(\bm{\sigma}, q) = 0 via a first-order Taylor series expansion about the current iterative state. By re-evaluating the flow direction \partial f / \partial \bm{\sigma} and hardening vector h at each iterate, the scalar plastic multiplier increment \Delta \gamma^{(k)} is calculated explicitly without computing second-order derivatives \partial^2 f / \partial \bm{\sigma}^2 or inverting local Hessian matrices \mathbf{\Xi}. - -## 2. Mathematical Formulation - -**Cutting Plane Linearized Yield Function Expansion** -$$ -f\left(\bm{\sigma}_{n+1}^{(k+1)}, q_{n+1}^{(k+1)}\right) \approx f_{n+1}^{(k)} + \left. \frac{\partial f}{\partial \bm{\sigma}} \right|_{n+1}^{(k)} : \Delta \bm{\sigma}_{n+1}^{(k)} + \left. \frac{\partial f}{\partial q} \right|_{n+1}^{(k)} \Delta q_{n+1}^{(k)} = 0 -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 148_ - -**Explicit Plastic Multiplier Increment Formula** -$$ -\Delta \gamma_{n+1}^{(k)} = \frac{f_{n+1}^{(k)}}{\left. \frac{\partial f}{\partial \bm{\sigma}} \right|_{n+1}^{(k)} : \mathbf{C} : \left. \frac{\partial f}{\partial \bm{\sigma}} \right|_{n+1}^{(k)} + \left. \frac{\partial f}{\partial q} \right|_{n+1}^{(k)} \cdot h_{n+1}^{(k)}} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.6, p. 148_ - -**Iterative Plastic Strain and Hardening Updates** -$$ -\bm{\varepsilon}^p_{(k+1)} = \bm{\varepsilon}^p_{(k)} + \Delta \gamma_{n+1}^{(k)} \left. \frac{\partial f}{\partial \bm{\sigma}} \right|_{n+1}^{(k)}, \quad q_{n+1}^{(k+1)} = q_{n+1}^{(k)} - \Delta \gamma_{n+1}^{(k)} h_{n+1}^{(k)} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.6, p. 148_ - -**Iterative Cauchy Stress Update** -$$ -\bm{\sigma}_{n+1}^{(k+1)} = \mathbf{C} : \left( \bm{\varepsilon}_{n+1} - \bm{\varepsilon}^p_{(k+1)} \right) -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.6, p. 148_ - -**Notation:** -\bm{\sigma}_{n+1}^{(k)}: Cauchy stress tensor at iteration k; q_{n+1}^{(k)}: internal hardening variable at iteration k; f: yield function; \mathbf{C}: fourth-order elastic stiffness tensor; \Delta \gamma_{n+1}^{(k)}: scalar plastic multiplier increment; \bm{\varepsilon}^p: plastic strain tensor; h: plastic hardening function; \mathrm{TOL}: yield tolerance threshold. - - -## 3. Algorithmic Implementation - -**Cutting Plane Return-Mapping Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: plastic strain } \bm{\varepsilon}^p_n, \text{ hardening variable } q_n, \text{ total strain } \bm{\varepsilon}_{n+1}, \text{ and elasticity tensor } \mathbf{C}$ -\State $\text{Initialize iteration counter } k = 0, \bm{\varepsilon}^p_{(0)} = \bm{\varepsilon}^p_n, q_{n+1}^{(0)} = q_n, \gamma_{n+1}^{(0)} = 0$ -\State $\bm{\sigma}_{n+1}^{(0)} = \mathbf{C} : (\bm{\varepsilon}_{n+1} - \bm{\varepsilon}^p_{(0)})$ -\State $f_{n+1}^{(0)} = f(\bm{\sigma}_{n+1}^{(0)}, q_{n+1}^{(0)})$ -\If{$f_{n+1}^{(0)} \le \text{TOL}$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}_{n+1}^{(0)}, \quad \bm{\varepsilon}^p_{n+1} = \bm{\varepsilon}^p_n, \quad q_{n+1} = q_n$ -\Return $\text{Step is elastic; return trial state}$ -\Else -\EndIf -\While{$f_{n+1}^{(k)} > \text{TOL}$} -\State $\mathbf{n}^{(k)} = \left.\frac{\partial f}{\partial \bm{\sigma}}\right|_{n+1}^{(k)}, \quad h^{(k)} = h(\bm{\sigma}_{n+1}^{(k)}, q_{n+1}^{(k)})$ -\State $\Delta \gamma_{n+1}^{(k)} = \frac{f_{n+1}^{(k)}}{\mathbf{n}^{(k)} : \mathbf{C} : \mathbf{n}^{(k)} + \left.\frac{\partial f}{\partial q}\right|_{n+1}^{(k)} \cdot h^{(k)}}$ -\State $\bm{\varepsilon}^p_{(k+1)} = \bm{\varepsilon}^p_{(k)} + \Delta \gamma_{n+1}^{(k)} \mathbf{n}^{(k)}$ -\State $q_{n+1}^{(k+1)} = q_{n+1}^{(k)} - \Delta \gamma_{n+1}^{(k)} h^{(k)}$ -\State $\gamma_{n+1}^{(k+1)} = \gamma_{n+1}^{(k)} + \Delta \gamma_{n+1}^{(k)}$ -\State $\bm{\sigma}_{n+1}^{(k+1)} = \mathbf{C} : (\bm{\varepsilon}_{n+1} - \bm{\varepsilon}^p_{(k+1)})$ -\State $f_{n+1}^{(k+1)} = f(\bm{\sigma}_{n+1}^{(k+1)}, q_{n+1}^{(k+1)})$ -\State $k = k + 1$ -\EndWhile -\Return $\text{Return updated stress } \bm{\sigma}_{n+1}, \text{ plastic strain } \bm{\varepsilon}^p_{n+1}, \text{ and hardening variable } q_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.6, p. 148_ - - -## 4. Known Pitfalls - -- **Loss of Quadratic Convergence in Global Implicit Finite Element Solvers**: Because the cutting plane algorithm evaluates gradients at intermediate iterates without forming exact second-order Hessian matrices, exact algorithmic consistent tangent operators cannot be derived, causing global Newton-Raphson iterations to revert to linear convergence. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 145, 148)_ -- **Spurious Iterative Drift for Highly Curved Yield Surfaces**: For non-linear yield surfaces with high localized curvature (such as GTN or cap models), first-order Taylor expansion approximations in the cutting plane method can cause iterative drift or slow convergence compared to fully implicit closest point projection schemes. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 143, 148)_ - -## References - -- Simo_Hughes_1998_Computational inelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-drucker-prager.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-drucker-prager.md deleted file mode 100644 index 495dcfd..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-drucker-prager.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: plasticity-drucker-prager -title: Drucker-Prager Yield & Non-Associative Flow -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- yield-criterion -- drucker-prager -- non-associative -- friction -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-invariants - type: requires - weight: 1.0 -- to: plasticity-von-mises - type: refines - weight: 0.9 -- to: constit-stress-update-architecture - type: requires - weight: 0.9 -- to: constit-thermodynamic-framework - type: requires - weight: 0.8 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Drucker-Prager Yield & Non-Associative Flow - -## Summary - -Drucker-Prager yield criterion models pressure-dependent shear strength in frictional materials using a conical yield surface with non-associative dilatancy and specialized apex return mapping. - -## 1. Core Concept - -The Drucker-Prager yield criterion extends von Mises plasticity to pressure-dependent materials (such as soil, concrete, and rock) by introducing a hydrostatic stress term into the yield condition, forming a smooth cone in principal stress space with an apex on the hydrostatic axis. To prevent unphysical volumetric dilation under shear, a non-associative plastic potential g(\bm{\sigma}) is employed with an independent dilatancy angle \psi, which renders the elastoplastic tangent operator non-symmetric. When trial elastic stresses project beyond the conical yield surface above the apex transition boundary, a dedicated apex return mapping algorithm projects stress directly to the singularity point, zeroing deviatoric stress. - -## 2. Mathematical Formulation - -**Drucker-Prager Yield Function** -$$ -f(\bm{\sigma}) = \sqrt{J_2} + \alpha I_1 - k = 0, \quad \alpha = \frac{2 \sin\phi}{\sqrt{3}(3 - \sin\phi)}, \quad k = \frac{6 c_{coh} \cos\phi}{\sqrt{3}(3 - \sin\phi)} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 228, 244; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598_ - -**Non-Associative Plastic Potential Function** -$$ -g(\bm{\sigma}) = \sqrt{J_2} + \alpha_g I_1 - k_g, \quad \alpha_g = \frac{2 \sin\psi}{\sqrt{3}(3 - \sin\psi)} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 231-232_ - -**Non-Symmetric Algorithmic Tangent Operator** -$$ -\mathbf{D}^{\mathrm{alg}} = \mathbf{A}^{-1} : \mathbf{D}^e - \frac{\left( \mathbf{A}^{-1} : \mathbf{D}^e : \mathbf{n} \right) \otimes \left( \mathbf{m}^T : \mathbf{A}^{-1} : \mathbf{D}^e \right)}{\mathbf{n}^T : \mathbf{A}^{-1} : \mathbf{D}^e : \mathbf{m} + h} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.7, p. 251-252_ - -**Apex Singularity Return Condition** -$$ -\bm{\sigma}_{apex} = \frac{k}{3 \alpha} \mathbf{I}, \quad \text{for } I_1^{\mathrm{tr}} \ge \frac{k}{\alpha} + \frac{G \sqrt{2}}{K \alpha} \sqrt{J_2^{\mathrm{tr}}} -$$ -_Source: Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 600; Simplify_radial_return_Part_1.pdf p. 307_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; \bm{s}: deviatoric stress tensor; J_2: second invariant of deviatoric stress; I_1: first invariant of stress tensor; \phi: internal friction angle; \psi: dilatancy angle; c_{coh}: cohesion coefficient; \alpha, k: Drucker-Prager yield parameters; \alpha_g, k_g: plastic potential parameters; \mathbf{n}: yield surface gradient vector (\partial f / \partial \bm{\sigma}); \mathbf{m}: flow direction vector (\partial g / \partial \bm{\sigma}); \mathbf{D}^{\mathrm{alg}}: consistent elastoplastic tangent tensor; \bm{\sigma}_{apex}: hydrostatic apex stress tensor. - - -## 3. Algorithmic Implementation - -**Drucker-Prager Return Mapping and Apex Singularity Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given trial elastic stress } \bm{\sigma}^{\mathrm{tr}}, \text{ bulk modulus } K, \text{ shear modulus } G, \text{ and material parameters } \alpha, k, \alpha_g$ -\State $I_1^{\mathrm{tr}} = \mathrm{tr}(\bm{\sigma}^{\mathrm{tr}}), \quad \bm{s}^{\mathrm{tr}} = \bm{\sigma}^{\mathrm{tr}} - \frac{1}{3} I_1^{\mathrm{tr}} \mathbf{I}, \quad J_2^{\mathrm{tr}} = \frac{1}{2} \bm{s}^{\mathrm{tr}} : \bm{s}^{\mathrm{tr}}$ -\State $f^{\mathrm{tr}} = \sqrt{J_2^{\mathrm{tr}}} + \alpha I_1^{\mathrm{tr}} - k$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}}, \quad \mathbf{D}^{\mathrm{alg}} = \mathbf{D}^e$ -\Return $\text{Step is elastic; accept trial state}$ -\ElsIf{$\alpha I_1^{\mathrm{tr}} - k + \frac{9 K \alpha \alpha_g}{G} \sqrt{J_2^{\mathrm{tr}}} \ge 0 \quad \text{(Apex Region)}$} -\State $\bm{\sigma}_{n+1} = \frac{k}{3 \alpha} \mathbf{I}, \quad \mathbf{D}^{\mathrm{alg}} = \mathbf{O}$ -\Return $\text{Return apex hydrostatic stress state}$ -\Else -\State $\Delta \gamma = \frac{f^{\mathrm{tr}}}{G + 9 K \alpha \alpha_g}$ -\State $\bm{s}_{n+1} = \left( 1 - \frac{G \Delta \gamma}{\sqrt{J_2^{\mathrm{tr}}}} \right) \bm{s}^{\mathrm{tr}}, \quad I_{1,n+1} = I_1^{\mathrm{tr}} - 9 K \alpha_g \Delta \gamma$ -\State $\bm{\sigma}_{n+1} = \bm{s}_{n+1} + \frac{1}{3} I_{1,n+1} \mathbf{I}$ -\State $\mathbf{D}^{\mathrm{alg}} = \text{Form non-symmetric consistent tangent from } \mathbf{m} \neq \mathbf{n}$ -\EndIf -\Return $\text{Return updated stress } \bm{\sigma}_{n+1} \text{ and algorithmic tangent } \mathbf{D}^{\mathrm{alg}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 244, 251-252; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 600; Simplify_radial_return_Part_1.pdf p. 307_ - - -## 4. Known Pitfalls - -- **Spurious Volumetric Expansion from Associative Flow Assumptions**: Enforcing an associative flow rule (\psi = \phi) in Drucker-Prager plasticity severely overpredicts plastic volume growth (dilatancy) under shear, causing unrealistic uplift in geotechnical and soil-structure simulations. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 231-232; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598)_ -- **Division by Zero and Convergence Failure at the Apex Singularity**: Applying smooth return mapping derivative formulas \bm{s} / \sqrt{J_2} when trial stress projects near or above the hydrostatic apex (\sqrt{J_2^{\mathrm{tr}}} \to 0) causes division by zero; explicit apex projection logic must be enforced. _(Source: Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 600; Simplify_radial_return_Part_1.pdf p. 307)_ -- **Loss of Quadratic Solver Convergence from Symmetrizing Non-Associative Moduli**: Forcing major symmetry on the algorithmic tangent tensor \mathbf{D}^{\mathrm{alg}} when \psi \neq \phi discards off-diagonal flow terms, degrading global Newton-Raphson convergence rates. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.7, p. 251-252)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- Simplify_radial_return_Part_1.pdf -- Simplify_radial_return_Part_2.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-duvaut-lions.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-duvaut-lions.md deleted file mode 100644 index e02f39a..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-duvaut-lions.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -id: plasticity-duvaut-lions -title: Duvaut-Lions Viscoplastic Regularization -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- viscoplasticity -- duvaut-lions -- regularisation -- relaxation -status: tentative -confidence: 0.85 -source: hybrid -confidence_floor: 0.7 -edges: -- to: plasticity-radial-return - type: requires - weight: 1.0 - note: Duvaut-Lions calls the rate-independent return mapping inside its update -- to: plasticity-perzyna - type: contradicts - weight: 0.5 - note: Same regularisation goal; different algorithm — Duvaut-Lions has closed form, Perzyna requires inner Newton -- to: constit-stress-update-architecture - type: requires - weight: 1.0 - note: Same operator-split scaffolding; relaxation interpolates trial and rate-independent stress -- to: plasticity-peirce-rate-tangent - type: requires - weight: 0.6 - note: Borrows the Peirce-Shih-Needleman rate-tangent modulus relation for the Duvaut-Lions consistent tangent -load_with: -- plasticity-perzyna -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Duvaut-Lions Viscoplastic Regularization - -## Summary - -Duvaut-Lions viscoplastic regularisation expresses rate-dependent plasticity through a relaxation differential equation $\dot{\boldsymbol{\sigma}}=\mathbb{C}\colon\dot{\boldsymbol{\varepsilon}}-(1/\eta)(\boldsymbol{\sigma}-\bar{\boldsymbol{\sigma}})$ where $\bar{\boldsymbol{\sigma}}$ is the rate-independent (closest-point projected) stress. Backward Euler integration produces a CLOSED-FORM update: $\boldsymbol{\sigma}_{n+1}=(\eta/(\eta+\Delta t))\,\boldsymbol{\sigma}^{\mathrm{trial}}+(\Delta t/(\eta+\Delta t))\,\bar{\boldsymbol{\sigma}}_{n+1}$, where $\bar{\boldsymbol{\sigma}}_{n+1}$ is obtained from the standard rate-independent return mapping at the same trial state. The interpolation factor $\Delta t/(\eta+\Delta t)$ ranges from $0$ (purely elastic, $\eta\to\infty$) to $1$ (rate-independent, $\eta\to 0$). The algorithmic tangent inherits the same linear interpolation: $\mathbb{C}^{\mathrm{alg}}=(\eta/(\eta+\Delta t))\mathbb{C}^e+(\Delta t/(\eta+\Delta t))\mathbb{C}^{\mathrm{alg,RI}}$. Compared to Perzyna: same regularisation goal, but Duvaut-Lions has CLOSED-FORM update (no inner Newton), exact rate-independent limit at $\eta=0$, and uses the rate-independent return mapping as a black box. Best when the rate-independent solver is robust; cleaner algorithmic structure than Perzyna for production codes. - -## 1. Core Concept - -Duvaut-Lions takes a different approach to viscoplasticity than Perzyna: instead of replacing the yield consistency with rate-dependent overstress, it adds a relaxation term to the constitutive ODE that pulls the stress toward the rate-independent yield surface at finite rate $\eta$. The geometric picture: the trial elastic stress is projected onto the rate-independent yield surface to give $\bar{\boldsymbol{\sigma}}$; the actual stress $\boldsymbol{\sigma}_{n+1}$ is a weighted average of the trial (no relaxation) and $\bar{\boldsymbol{\sigma}}$ (full relaxation), with weights determined by the relaxation time $\eta$ relative to the time step $\Delta t$. The algorithmic structure is much cleaner than Perzyna: NO inner Newton, the rate-independent return mapping is called as a subroutine, and the result is a single linear interpolation. The drawback is that Duvaut-Lions requires the rate-independent return mapping to converge robustly — for very stiff yield surfaces near apex / vertex regions where rate-independent return mapping itself struggles, the Duvaut-Lions wrapper inherits those difficulties. The Peirce tangent modulus relation gives the consistent tangent in closed form: $\mathbb{C}^{\mathrm{alg}}=(\eta/(\eta+\Delta t))\mathbb{C}^e+(\Delta t/(\eta+\Delta t))\mathbb{C}^{\mathrm{alg,RI}}$, where $\mathbb{C}^{\mathrm{alg,RI}}$ is the rate-independent algorithmic tangent (e.g., Souza-Neto J2). Production-code-friendly for codes with mature rate-independent infrastructure. - -## 2. Mathematical Formulation - -**Duvaut-Lions rate equation** -$$ -\dot{\boldsymbol{\sigma}} = \mathbb{C}^e\colon\dot{\boldsymbol{\varepsilon}} - \frac{1}{\eta}\,(\boldsymbol{\sigma} - \bar{\boldsymbol{\sigma}}) -$$ - -**Backward-Euler integration** -$$ -\boldsymbol{\sigma}_{n+1} - \boldsymbol{\sigma}_n = \mathbb{C}^e\colon\Delta\boldsymbol{\varepsilon} - \frac{\Delta t}{\eta}\,(\boldsymbol{\sigma}_{n+1} - \bar{\boldsymbol{\sigma}}_{n+1}) -$$ - -**Closed-form update (linear interpolation)** -$$ -\boldsymbol{\sigma}_{n+1} = \frac{\eta}{\eta + \Delta t}\,\boldsymbol{\sigma}^{\mathrm{trial}} + \frac{\Delta t}{\eta + \Delta t}\,\bar{\boldsymbol{\sigma}}_{n+1} -$$ - -**Limits** -$$ -\eta\to 0\,\Rightarrow\,\boldsymbol{\sigma}_{n+1}\to\bar{\boldsymbol{\sigma}}_{n+1}\,\text{(rate-independent)},\\ -\eta\to\infty\,\Rightarrow\,\boldsymbol{\sigma}_{n+1}\to\boldsymbol{\sigma}^{\mathrm{trial}}\,\text{(elastic)} -$$ - -**Internal-variable update** -$$ -\boldsymbol{\varepsilon}^p_{n+1} = \boldsymbol{\varepsilon}^p_n + \frac{\Delta t}{\eta + \Delta t}\,(\bar{\boldsymbol{\varepsilon}}^p_{n+1} - \boldsymbol{\varepsilon}^p_n) -$$ - -**Algorithmic tangent (Peirce form)** -$$ -\mathbb{C}^{\mathrm{alg}} = \frac{\eta}{\eta+\Delta t}\,\mathbb{C}^e + \frac{\Delta t}{\eta+\Delta t}\,\bar{\mathbb{C}}^{\mathrm{alg,RI}} -$$ - -**Comparison with Perzyna** -$$ -\text{Perzyna: } \dot\gamma = (1/\eta)\langle f/\sigma_0\rangle^m,\,\text{requires inner Newton on}\,\Delta\gamma\\ -\text{Duvaut-Lions: closed-form interpolation between}\,\boldsymbol{\sigma}^{\mathrm{trial}}\,\text{and}\,\bar{\boldsymbol{\sigma}}_{n+1} -$$ - -**Effective overstress exponent** -$$ -\dot{\bar\varepsilon}^p = (\Delta t/(\eta+\Delta t))\,\dot{\bar\varepsilon}^{p,\mathrm{RI}} -$$ - -**Peirce regularisation in shear-band analysis** -$$ -\ell_{\mathrm{band}} \sim c_s\,\eta\,\sqrt{\Delta t/\eta}\,\text{at intermediate rate} -$$ - -**Notation:** -{'\\bar{\\boldsymbol{\\sigma}}': 'Rate-independent return-mapped stress', '\\eta': 'Relaxation time / viscosity parameter', '\\Delta t': 'Time step', '\\eta/(\\eta+\\Delta t)': 'Trial weight in interpolation', '\\Delta t/(\\eta+\\Delta t)': 'Relaxation weight in interpolation (range $[0, 1]$)', '\\bar{\\mathbb{C}}^{\\mathrm{alg,RI}}': 'Rate-independent algorithmic tangent (e.g., Souza-Neto J2)', '\\mathbb{C}^e': 'Elastic tangent', '\\bar{\\boldsymbol{\\varepsilon}}^p_{n+1}': 'Rate-independent end-of-step plastic strain'} - - -## 3. Algorithmic Implementation - -**Duvaut-Lions Closed-Form Update** -$$ -\begin{algorithmic} -\State State \text{input} \colon \boldsymbol{\sigma}_n,\boldsymbol{\varepsilon}^p_n,\bar\varepsilon^p_n,\Delta\boldsymbol{\varepsilon},\eta,\Delta t,\,\text{rate-indep return mapping}\,\mathrm{ReturnMapRI}$ -\State State \boldsymbol{\sigma}^{\mathrm{trial}} \gets \boldsymbol{\sigma}_n + \mathbb{C}^e\colon\Delta\boldsymbol{\varepsilon} -\State State \bar{\boldsymbol{\sigma}}_{n+1},\bar{\boldsymbol{\varepsilon}}^p_{n+1},\bar{\bar\varepsilon}^p_{n+1},\bar{\mathbb{C}}^{\mathrm{alg,RI}} \gets \mathrm{ReturnMapRI}(\boldsymbol{\sigma}^{\mathrm{trial}},\bar\varepsilon^p_n,\boldsymbol{\varepsilon}^p_n) -\State State w \gets \Delta t/(\eta + \Delta t) -\State State \boldsymbol{\sigma}_{n+1} \gets (1-w)\,\boldsymbol{\sigma}^{\mathrm{trial}} + w\,\bar{\boldsymbol{\sigma}}_{n+1} -\State State \boldsymbol{\varepsilon}^p_{n+1} \gets \boldsymbol{\varepsilon}^p_n + w\,(\bar{\boldsymbol{\varepsilon}}^p_{n+1} - \boldsymbol{\varepsilon}^p_n) -\State State \bar\varepsilon^p_{n+1} \gets \bar\varepsilon^p_n + w\,(\bar{\bar\varepsilon}^p_{n+1} - \bar\varepsilon^p_n) -\State State \mathbb{C}^{\mathrm{alg}} \gets (1-w)\,\mathbb{C}^e + w\,\bar{\mathbb{C}}^{\mathrm{alg,RI}} -\State Return \boldsymbol{\sigma}_{n+1},\boldsymbol{\varepsilon}^p_{n+1},\bar\varepsilon^p_{n+1},\mathbb{C}^{\mathrm{alg}} -\end{algorithmic} -$$ -Taichi Mapping: Cleanest viscoplastic algorithm: ONE call to rate-independent return mapping, ONE linear interpolation, no inner Newton. Per-Gauss-point cost: same as rate-independent return mapping plus $\sim 50$ FMAs for the interpolation. The rate-independent return mapping subroutine is a black box — works for any yield surface (J2, Drucker-Prager, GTN, Hill48). The simplicity makes Duvaut-Lions production-code-friendly. - -**Choose Between Perzyna and Duvaut-Lions** -$$ -\begin{algorithmic} -\State State \text{decision factors:} -\State State \text{(a) need exact rate-independent at}\,\eta=0\,\to\,\text{Duvaut-Lions (closed-form recovery)} -\State State \text{(b) physical Perzyna calibration available}\,\to\,\text{Perzyna (overstress exponent}\,m) -\State State \text{(c) production-code simplicity}\,\to\,\text{Duvaut-Lions (no inner Newton)} -\State State \text{(d) very stiff overstress (m > 10)}\,\to\,\text{Duvaut-Lions (Perzyna fails)} -\State State \text{(e) need power-law strain-rate sensitivity}\,\to\,\text{Perzyna (m parameter)} -\State Return \text{recommended choice} -\end{algorithmic} -$$ -Taichi Mapping: Use this decision template at model-design time. Most production codes default to Duvaut-Lions for simplicity and robustness; specialised dynamic-loading codes (ballistics, machining) often need Perzyna's power-law overstress for accurate rate-sensitivity calibration. Document the choice in the constitutive interface and validate against experimental rate sweeps. - -**Calibrate $\eta$ from Strain-Rate-Sensitivity Data** -$$ -\begin{algorithmic} -\State State \text{input} \colon \{(\sigma_Y, \dot{\bar\varepsilon}^p)\}\,\text{at multiple rates} -\State State \text{Duvaut-Lions steady state: } \sigma_Y(\dot\gamma) = \bar\sigma_Y + \eta\,\dot\gamma -\State State \text{linear regression}\,\sigma_Y\,\text{vs}\,\dot\gamma\,\text{gives slope}\,\eta\,\text{and intercept}\,\bar\sigma_Y -\State Return \eta -\end{algorithmic} -$$ -Taichi Mapping: Off-line calibration. Duvaut-Lions has only ONE rate parameter ($\eta$); linear in strain rate. For materials with power-law rate sensitivity, this is a coarser model than Perzyna's two-parameter $(\eta, m)$. Default values: $\eta\sim 10^{-4}$ s for most metals; smaller for harder alloys, larger for soft polymers / rubbers. - - -## 4. Known Pitfalls - -- **Confusion with Perzyna**: Both are rate-dependent regularisations but have DIFFERENT algorithmic structure. Perzyna: replace yield consistency with overstress; requires inner Newton. Duvaut-Lions: interpolate between trial and rate-independent stress; closed form. Don't mix the two in the same constitutive code; the calibrated $\eta$ values are not interchangeable between formulations. -- **Rate-independent return mapping must converge robustly**: Duvaut-Lions calls the rate-independent return mapping as a black box; if that subroutine fails (e.g., near Drucker-Prager apex, or for non-convex yield surface) the Duvaut-Lions wrapper fails too. Make the rate-independent code bulletproof first; THEN wrap with Duvaut-Lions for rate-dependence. -- **Wrong choice of $\eta$ relative to $\Delta t$**: The interpolation weight $w=\Delta t/(\eta+\Delta t)$ depends on the time step. For a given material $\eta$, varying $\Delta t$ changes the effective rate sensitivity: $\Delta t\ll\eta$ produces nearly-elastic response, $\Delta t\gg\eta$ produces nearly-rate-independent. Mesh / time-step independence requires $\eta$ chosen for the LOADING rate of interest, not arbitrarily. -- **Internal-variable interpolation**: Duvaut-Lions interpolates not just stress but ALL state variables (plastic strain, hardening, damage). Forgetting to interpolate the internal variables produces inconsistent state — stress evolves rate-dependently while plastic strain evolves rate-independently. Apply the same weight $w$ to every state variable. -- **Linear vs power-law rate sensitivity**: Duvaut-Lions implies LINEAR rate sensitivity (slope $\eta$ in $\sigma_Y$ vs $\dot{\bar\varepsilon}^p$). Real metals show POWER-LAW rate sensitivity ($\sigma_Y\sim(\dot{\bar\varepsilon}^p)^{1/m}$). For accurate rate-sensitivity calibration use Perzyna's power-law form; Duvaut-Lions is a first-order approximation. -- **Singular limits not numerically robust**: $\eta=0$ exactly recovers rate-independent (good); $\eta\to\infty$ recovers elastic (good). But round-off can give $\eta=10^{-15}$ which produces a noisy interpolation weight near 1. Guard with $w=\min(1, \Delta t/(\eta+\Delta t))$ and $w=\max(0, w)$ to keep the interpolation in $[0, 1]$. -- **Algorithmic tangent inherits $\bar{\mathbb{C}}^{\mathrm{alg,RI}}$ asymmetry**: For non-associated rate-independent plasticity (Drucker-Prager with $\beta\ne\alpha$), $\bar{\mathbb{C}}^{\mathrm{alg,RI}}$ is asymmetric. The Duvaut-Lions interpolation $(1-w)\mathbb{C}^e+w\,\bar{\mathbb{C}}^{\mathrm{alg,RI}}$ is also asymmetric (since $\mathbb{C}^e$ is symmetric but adding asymmetric piece breaks symmetry). Pass through to the global FEM with GMRES / Bi-CGSTAB; do not symmetrise. -- **Source notebook coverage limited**: Duvaut-Lions is mentioned in dynamic-plasticity / softening-regularisation literature but the source notebook (be555674-...) covers it less thoroughly than Perzyna. Equations and structure cross-checked from Simo-Hughes (1998); confidence reduced ($0.85$) accordingly. - -## References - -- Duvaut & Lions (1972) — Inequalities in Mechanics and Physics (original variational formulation) -- Simo & Hughes (1998) — Computational Inelasticity, Ch. 4 (Duvaut-Lions backward-Euler closed-form, comparison with Perzyna) -- Peirce, Shih & Needleman (1984) — A tangent modulus method for rate dependent solids (algorithmic tangent for viscoplastic regularisation) -- Souza Neto, Peric, Owen (2008) — Computational Methods for Plasticity (Duvaut-Lions in production codes) diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-exponential-map.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-exponential-map.md deleted file mode 100644 index b4c080d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-exponential-map.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: plasticity-exponential-map -title: Exponential Map for $\mathbf{F}^p$ Update -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- finite-strain -- exponential-map -- multiplicative-split -- plastic-incompressibility -status: established -confidence: 0.9 -source: hybrid -edges: -- to: kinematics-multiplicative-decomp - type: requires - weight: 1.0 -- to: tensor-isotropic-functions - type: requires - weight: 1.0 -- to: kinematics-logarithmic-strain - type: feeds-into - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Exponential Map for $\mathbf{F}^p$ Update - -## Summary - -The exponential map integrates plastic deformation gradient updates in finite-strain multiplicative plasticity, preserving exact plastic incompressibility det(F^p) = 1. - -## 1. Core Concept - -In finite-strain elastoplasticity based on the multiplicative decomposition F = F^e F^p, integrating the plastic velocity gradient rate equation F_dot^p = L_p F^p using standard forward or backward Euler difference schemes leads to numerical volume drift. The exponential map return-mapping algorithm integrates the plastic flow equation over a discrete time step via the matrix exponential F^p_{n+1} = exp(Delta t L_p) F^p_n. For trace-free deviatoric plastic flow (tr L_p = 0), this exponential formulation preserves exact unimodular plastic incompressibility det F^p = 1. In principal elastic strain space, the tensor exponential map simplifies to a linear return mapping on logarithmic elastic strains, enabling exact algorithmic equivalence to infinitesimal return-mapping schemes. - -## 2. Mathematical Formulation - -**Multiplicative Plastic Deformation Gradient Exponential Update** -$$ -\mathbf{F}^p_{n+1} = \exp\left[ \Delta t \dot{\lambda} \mathbf{R}_{e,n+1}^T \cdot \left( \frac{\partial F}{\partial \bm{\tau}} \right)_{n+1} \cdot \mathbf{R}_{e,n+1} \right] \cdot \mathbf{F}^p_n -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 252; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 418, 421_ - -**Plastic Incompressibility Determinant Preservation** -$$ -\mathrm{tr}(\mathbf{L}_p) = 0 \implies \det\left(\mathbf{F}^p_{n+1}\right) = \det\left(\mathbf{F}^p_n\right) = 1 -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 252; Simo_Hughes_1998_Computational inelasticity.pdf p. 297_ - -**Equivalence to Logarithmic Elastic Strain Return Mapping** -$$ -\bm{\varepsilon}^e_{n+1} = \bm{\varepsilon}^{e,\mathrm{tr}} - \Delta \lambda \left. \frac{\partial F}{\partial \bm{\tau}} \right|_{n+1}, \quad \bm{\varepsilon}^e = \frac{1}{2}\ln\left(\mathbf{F}^e \cdot \mathbf{F}^{eT}\right) -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 252; Kim_FEA for Elastoplastic Problems.pdf p. 226_ - -**Left Cauchy-Green Elastic Tensor Spectral Exponential Recovery** -$$ -\mathbf{b}^e_{n+1} = \sum_{i=1}^3 \exp\left(2 \varepsilon^e_{i,n+1}\right) \mathbf{m}^i, \quad \mathbf{m}^i = \hat{\mathbf{n}}^i \otimes \hat{\mathbf{n}}^i -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 226, 228; Simo_Hughes_1998_Computational inelasticity.pdf p. 299-300_ - -**Notation:** -\mathbf{F}^p: plastic deformation gradient tensor; \mathbf{F}^e: elastic deformation gradient tensor; \mathbf{L}_p: plastic velocity gradient tensor; \mathbf{R}_e: elastic rotation tensor; \bm{\tau}: Kirchhoff stress tensor; \Delta \lambda: discrete plastic consistency multiplier; \bm{\varepsilon}^e: logarithmic elastic strain tensor; \bm{\varepsilon}^{e,\mathrm{tr}}: trial logarithmic elastic strain tensor; \mathbf{b}^e: elastic left Cauchy-Green deformation tensor; \varepsilon^e_i: principal logarithmic elastic strain components; \mathbf{m}^i: spectral eigenprojection tensors. - - -## 3. Algorithmic Implementation - -**Multiplicative Finite Strain Exponential Map Return-Mapping Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: total deformation gradient } \mathbf{F}_n, \text{ elastic deformation gradient } \mathbf{F}^e_n, \text{ plastic deformation gradient } \mathbf{F}^p_n, \text{ and displacement increment } \Delta \mathbf{u}$ -\State $\mathbf{F}_{n+1} = (\mathbf{I} + \nabla \Delta \mathbf{u}) \mathbf{F}_n, \quad \mathbf{f} = \mathbf{I} + \nabla \Delta \mathbf{u}$ -\State $\mathbf{F}^{e,\mathrm{tr}} = \mathbf{f} \mathbf{F}^e_n, \quad \bar{\mathbf{f}} = (\det \mathbf{f})^{-1/3} \mathbf{f}, \quad \mathbf{b}^{e,\mathrm{tr}} = \bar{\mathbf{f}} \mathbf{b}^e_n \bar{\mathbf{f}}^T$ -\State $\text{Compute trial principal logarithmic strains } \varepsilon^{e,\mathrm{tr}}_i = \frac{1}{2} \ln(\lambda^{\mathrm{tr}}_i) \text{ from eigenvalues } \lambda^{\mathrm{tr}}_i \text{ of } \mathbf{b}^{e,\mathrm{tr}}$ -\State $\bm{\tau}^{\mathrm{tr}} = \mathbf{D}^e : \bm{\varepsilon}^{e,\mathrm{tr}}, \quad f^{\mathrm{tr}} = f(\bm{\tau}^{\mathrm{tr}}, \mathbf{q}_n)$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\mathbf{b}^e_{n+1} = \mathbf{b}^{e,\mathrm{tr}}, \quad \mathbf{F}^p_{n+1} = \mathbf{F}^p_n, \quad \bm{\tau}_{n+1} = \bm{\tau}^{\mathrm{tr}}$ -\Return $\text{Step is elastic; return trial state}$ -\Else -\EndIf -\State $\varepsilon^e_{i,n+1} = \varepsilon^{e,\mathrm{tr}}_i - \Delta \lambda N_i, \quad \bm{\tau}_{n+1} = \sum_{i=1}^3 \tau^p_{i,n+1} \mathbf{m}^i$ -\State $\mathbf{b}^e_{n+1} = \sum_{i=1}^3 \exp(2 \varepsilon^e_{i,n+1}) \mathbf{m}^i, \quad \mathbf{F}^p_{n+1} = \exp\left[ \Delta \lambda \mathbf{N} \right] \cdot \mathbf{F}^p_n$ -\Return $\text{Return updated Kirchhoff stress } \bm{\tau}_{n+1}, \text{ elastic left Cauchy-Green tensor } \mathbf{b}^e_{n+1}, \text{ and plastic deformation gradient } \mathbf{F}^p_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 252; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 12.2, p. 421; Simo_Hughes_1998_Computational inelasticity.pdf Box 9.1, p. 299-300_ - - -## 4. Known Pitfalls - -- **Volumetric Drift from Standard Linear Difference Integration of Plastic Rate Equations**: Integrating plastic deformation gradient rate equations using standard forward or backward Euler linear updates (F^p_{n+1} = [I + Delta t L_p] F^p_n) fails to preserve det(F^p) = 1, accumulating unphysical volumetric plastic drift under finite strain. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 252; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 414, 418)_ -- **Coaxiality Assumption Breakdown in Non-Isotropic Plastic Flow**: Assuming principal axes of elastic left Cauchy-Green tensor b^e and Kirchhoff stress tau remain strictly coaxial during plastic correction introduces kinematic orientation errors under anisotropic hardening or non-associated flow. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 418; Kim_FEA for Elastoplastic Problems.pdf p. 225, 235)_ -- **Loss of Frame Invariance from Non-Objective Stress Integration**: Evaluating exponential maps without properly pulling back deformation gradients to rotation-neutralized intermediate frames violates principle of material frame indifference under large rigid body rotations. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 252; Simo_Hughes_1998_Computational inelasticity.pdf p. 295-297)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-general-return-mapping.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-general-return-mapping.md deleted file mode 100644 index e614661..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-general-return-mapping.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: plasticity-general-return-mapping -title: General Return Mapping (Backward Euler) -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- return-mapping -- backward-euler -- implicit-integration -- newton -status: established -confidence: 0.9 -source: hybrid -edges: -- to: constit-stress-update-architecture - type: requires - weight: 1.0 -- to: plasticity-radial-return - type: refines - weight: 0.9 -- to: plasticity-cpp-nonassociative - type: feeds-into - weight: 0.9 -- to: plasticity-consistent-tangent-general - type: feeds-into - weight: 1.0 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# General Return Mapping (Backward Euler) - -## Summary - -General return mapping integrates elastoplastic constitutive equations over finite strain increments using a backward Euler implicit integration scheme that enforces yield surface consistency at the end of the step. - -## 1. Core Concept - -The general backward Euler return-mapping algorithm integrates elastoplastic constitutive rate equations over discrete time increments [t_n, t_{n+1}]. Operating under an operator-split paradigm, the algorithm first computes an elastic predictor state with frozen internal plastic variables. If the trial elastic stress violates plastic admissibility (f^{tr} > 0), an implicit plastic corrector step projects the stress state back onto the yield surface. Local Newton-Raphson iterations solve the coupled discrete system enforcing plastic flow direction and yield consistency f(\bm{\sigma}_{n+1}, \bm{q}_{n+1}) = 0 at the step endpoint, ensuring unconditional algorithmic stability and path-independent state updates. - -## 2. Mathematical Formulation - -**Discrete Backward Euler Stress Update Relation** -$$ -\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}} - \Delta \gamma \mathbf{D}^e : \mathbf{m}_{n+1}, \quad \mathbf{m}_{n+1} = \left. \frac{\partial g}{\partial \bm{\sigma}} \right|_{n+1} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 143-144; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 242_ - -**Internal Hardening Variable Evolution Update** -$$ -\bm{q}_{n+1} = \bm{q}_n - \Delta \gamma \bm{h}(\bm{\sigma}_{n+1}, \bm{q}_{n+1}) -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 143; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 242_ - -**Step-End Plastic Yield Consistency Condition** -$$ -f(\bm{\sigma}_{n+1}, \bm{q}_{n+1}) = 0, \quad \Delta \gamma \ge 0, \quad f(\bm{\sigma}_{n+1}, \bm{q}_{n+1}) \Delta \gamma = 0 -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 143; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 242_ - -**Plastic Flow Residual Vector System** -$$ -\bm{R}_{\bm{\varepsilon}}(\bm{\sigma}_{n+1}, \bm{q}_{n+1}, \Delta \gamma) = -\bm{\varepsilon}^p_{n+1} + \bm{\varepsilon}^p_n + \Delta \gamma \mathbf{m}_{n+1} = \bm{0} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.5, p. 146_ - -**Notation:** -\bm{\sigma}_{n+1}: updated Cauchy stress tensor; \bm{\sigma}^{\mathrm{tr}}: elastic trial stress tensor; \mathbf{D}^e: fourth-order elastic stiffness tensor; \Delta \gamma: discrete plastic consistency parameter; f: yield function; g: plastic potential function; \mathbf{m}: plastic flow direction tensor (\partial g / \partial \bm{\sigma}); \mathbf{n}: yield surface normal tensor (\partial f / \partial \bm{\sigma}); \bm{q}: internal hardening state variable vector; \bm{h}: hardening evolution function; \bm{R}_{\bm{\varepsilon}}: local plastic flow residual tensor. - - -## 3. Algorithmic Implementation - -**General Backward Euler Return-Mapping Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: stress } \bm{\sigma}_n, \text{ plastic strain } \bm{\varepsilon}^p_n, \text{ internal variables } \bm{q}_n, \text{ and strain increment } \Delta \bm{\varepsilon}$ -\State $\bm{\sigma}^{\mathrm{tr}} = \bm{\sigma}_n + \mathbf{D}^e : \Delta \bm{\varepsilon}, \quad \bm{q}^{\mathrm{tr}} = \bm{q}_n, \quad f^{\mathrm{tr}} = f(\bm{\sigma}^{\mathrm{tr}}, \bm{q}^{\mathrm{tr}})$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}}, \quad \bm{\varepsilon}^p_{n+1} = \bm{\varepsilon}^p_n, \quad \bm{q}_{n+1} = \bm{q}_n$ -\Return $\text{Step is elastic; return trial state}$ -\Else -\EndIf -\While{$\|\bm{R}_{\bm{\sigma}}^{(k)}\| > \text{TOL}_1 \quad \text{or} \quad |f^{(k)}| > \text{TOL}_2$} -\State $\mathbf{n}^{(k)} = \left.\frac{\partial f}{\partial \bm{\sigma}}\right|_{n+1}^{(k)}, \quad \mathbf{m}^{(k)} = \left.\frac{\partial g}{\partial \bm{\sigma}}\right|_{n+1}^{(k)}, \quad \mathbf{\Xi}^{(k)} = \left[ \mathbf{D}^{e-1} + \Delta \gamma^{(k)} \frac{\partial^2 g}{\partial \bm{\sigma}^2} \right]^{-1}$ -\State $d\Delta \gamma = \frac{f^{(k)} - \mathbf{n}^{(k)} : \mathbf{\Xi}^{(k)} : \bm{R}_{\bm{\sigma}}^{(k)}}{\mathbf{n}^{(k)} : \mathbf{\Xi}^{(k)} : \mathbf{m}^{(k)} + H_{\mathrm{alg}}^{(k)}}$ -\State $d\bm{\sigma} = -\mathbf{\Xi}^{(k)} : \left[ \bm{R}_{\bm{\sigma}}^{(k)} + d\Delta \gamma \mathbf{m}^{(k)} \right]$ -\State $\bm{\sigma}_{n+1}^{(k+1)} = \bm{\sigma}_{n+1}^{(k)} + d\bm{\sigma}, \quad \Delta \gamma^{(k+1)} = \Delta \gamma^{(k)} + d\Delta \gamma, \quad k = k + 1$ -\EndWhile -\Return $\text{Return updated stress } \bm{\sigma}_{n+1}, \text{ plastic strain } \bm{\varepsilon}^p_{n+1}, \text{ and internal variables } \bm{q}_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 3.5, p. 146; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 242-246_ - - -## 4. Known Pitfalls - -- **Overtaking Trial Yield Boundary and Missing Unloading Transitions**: Evaluating trial elastic stress without verifying yield function admissibility f^{\mathrm{tr}} \le 0 can execute plastic corrector updates during elastic unloading, causing unphysical plastic dissipation and spurious stress drift. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 241-242; Kim_FEA for Elastoplastic Problems.pdf p. 203)_ -- **Loss of Quadratic Solver Convergence Using Non-Consistent Tangents**: Substituting the continuum elastoplastic tangent operator D^{ep} for the exact consistent algorithmic tangent operator in global Newton-Raphson iterations destroys asymptotic quadratic convergence, requiring excess global equilibrium iterations. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 145-147; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 38-39)_ -- **Ill-Conditioning near Non-Smooth Yield Surface Vertices**: Applying smooth backward Euler return mapping equations at non-differentiable yield surface corners or apices introduces singular Hessians \partial^2 g / \partial \bm{\sigma}^2 and division by zero, requiring multi-surface Koiter return algorithms or subdifferential formulations. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 212-215; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 252-253; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-hill48.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-hill48.md deleted file mode 100644 index c36ea05..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-hill48.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: plasticity-hill48 -title: Hill 1948 Anisotropic Yield -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- anisotropy -- hill48 -- sheet-metal -- r-values -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-invariants - type: requires - weight: 0.7 -- to: plasticity-von-mises - type: refines - weight: 1.0 -- to: constit-stress-update-architecture - type: requires - weight: 0.9 -- to: plasticity-lode-triaxiality - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Hill 1948 Anisotropic Yield - -## Summary - -Hill 1948 yield criterion extends von Mises plasticity to orthotropic anisotropic materials using a quadratic stress tensor formulation. - -## 1. Core Concept - -The Hill anisotropic yield criterion (Hill, 1948) generalizes classical isotropic J_2 von Mises plasticity to orthotropic materials such as rolled metals. Formulated as a quadratic function of stress components in principal anisotropy directions, the Hill yield function eliminates hydrostatic pressure dependence by enforcing \alpha_{11} = \alpha_{22} = \alpha_{33} = 0 from the broader Hoffman failure criterion. Under backward Euler implicit integration, the stress update is evaluated via an anisotropic projection matrix \mathbf{P}_{\alpha}, maintaining exact algorithmic return mapping. - -## 2. Mathematical Formulation - -**Hill Anisotropic Yield Function** -$$ -f(\bm{\sigma}) = \frac{1}{2} \bm{\sigma}^T \mathbf{P}_{\alpha} \bm{\sigma} - \bar{\sigma}^2 = 0 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.5, p. 246_ - -**Anisotropic Projection Matrix P_\alpha** -$$ -\mathbf{P}_{\alpha} = \begin{bmatrix} 2(\alpha_{31}+\alpha_{12}) & -2\alpha_{12} & -2\alpha_{31} & 0 & 0 & 0 \\ -2\alpha_{12} & 2(\alpha_{23}+\alpha_{12}) & -2\alpha_{23} & 0 & 0 & 0 \\ -2\alpha_{31} & -2\alpha_{23} & 2(\alpha_{31}+\alpha_{23}) & 0 & 0 & 0 \\ 0 & 0 & 0 & 6\alpha_{44} & 0 & 0 \\ 0 & 0 & 0 & 0 & 6\alpha_{55} & 0 \\ 0 & 0 & 0 & 0 & 0 & 6\alpha_{66} \end{bmatrix} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.5, p. 246_ - -**Backward Euler Anisotropic Stress Update** -$$ -\bm{\sigma}_{j+1} = \left( \mathbf{I} + \Delta \lambda \mathbf{D}^e \mathbf{P}_{\alpha} \right)^{-1} \bm{\sigma}^{\mathrm{tr}} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.5, p. 246_ - -**Fourth-Order Hill Tensor Norm Formulation** -$$ -f(\mathbf{T}) = \|\mathbf{T}\|_{\mathbf{H}} - \sqrt{\frac{2}{3}} y_0 = 0, \quad \|\mathbf{T}\|_{\mathbf{H}} = \sqrt{\mathbf{T} : \mathbf{H} : \mathbf{T}} -$$ -_Source: Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf p. 287_ - -**Notation:** -\bm{\sigma}: Cauchy stress vector in Voigt notation; \mathbf{P}_{\alpha}: symmetric anisotropic projection matrix; \alpha_{ij}: anisotropic yield parameters; \bar{\sigma}, y_0: equivalent flow yield stress; \mathbf{D}^e: elastic stiffness matrix; \Delta \lambda: discrete plastic multiplier; \mathbf{H}: fourth-order Hill anisotropy tensor; \mathbf{T}: stress tensor in logarithmic strain space. - - -## 3. Algorithmic Implementation - -**Hill Anisotropic Plasticity Return-Mapping Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given elastic trial stress } \bm{\sigma}^{\mathrm{tr}}, \text{ elastic stiffness matrix } \mathbf{D}^e, \text{ and anisotropic projection matrix } \mathbf{P}_{\alpha}$ -\State $f^{\mathrm{tr}} = \frac{1}{2} (\bm{\sigma}^{\mathrm{tr}})^T \mathbf{P}_{\alpha} \bm{\sigma}^{\mathrm{tr}} - \bar{\sigma}_0^2$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}}$ -\Return $\text{Step is elastic; accept trial stress}$ -\Else -\EndIf -\State $\bm{\sigma}_{n+1} = (\mathbf{I} + \Delta \lambda \mathbf{D}^e \mathbf{P}_{\alpha})^{-1} \bm{\sigma}^{\mathrm{tr}}$ -\Return $\text{Return updated anisotropic Cauchy stress } \bm{\sigma}_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.5, p. 246_ - - -## 4. Known Pitfalls - -- **Assuming Isotropic Flow in Anisotropic Rolled Sheet Metals**: Applying isotropic J2 von Mises yield criteria to rolled sheet metals miscalculates directional yield strengths and plastic flow, producing errors in localized necking and springback predictions. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.5, p. 246; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf p. 287)_ -- **Ill-Conditioned Matrix Inversion in Anisotropic Return Mapping**: Inverting (\mathbf{I} + \Delta \lambda \mathbf{D}^e \mathbf{P}_{\alpha}) without validating positive definiteness of anisotropic matrix \mathbf{P}_{\alpha} causes matrix singular ill-conditioning during local return mapping iterations. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf Box 7.5, p. 246)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-isotropic-hardening.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-isotropic-hardening.md deleted file mode 100644 index c111aaa..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-isotropic-hardening.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: plasticity-isotropic-hardening -title: Isotropic Hardening Laws -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- hardening -- voce -- swift -- calibration -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-von-mises - type: feeds-into - weight: 1.0 -- to: constit-stress-update-architecture - type: feeds-into - weight: 0.9 -- to: plasticity-kinematic-hardening - type: feeds-into - weight: 0.7 -- to: plasticity-johnson-cook - type: refines - weight: 0.6 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Isotropic Hardening Laws - -## Summary - -Isotropic hardening laws quantify the uniform expansion of the yield surface in stress space as equivalent plastic strain accumulates during inelastic deformation. - -## 1. Core Concept - -Isotropic hardening models describe the evolution of material yield strength as a function of plastic deformation history, expanding the elastic domain uniformly in all stress directions without shifting the yield surface center. In rate-independent and rate-dependent J2 plasticity, isotropic hardening is driven either by the strain-hardening hypothesis, where the internal state variable is equivalent plastic strain \bar{\varepsilon}^p = \int \sqrt{\frac{2}{3} \dot{\bm{\varepsilon}}^p : \dot{\bm{\varepsilon}}^p} dt, or by the work-hardening hypothesis, where plastic work \kappa = \int \bm{\sigma} : \dot{\bm{\varepsilon}}^p dt acts as the history parameter. Canonical mathematical formulations include linear isotropic hardening, nonlinear Voce exponential saturation, and power-law hardening rules. - -## 2. Mathematical Formulation - -**Strain-Hardening Hypothesis Rate Equation** -$$ -\dot{\kappa} = \dot{\bar{\varepsilon}}^p = \sqrt{\frac{2}{3} \dot{\bm{\varepsilon}}^p : \dot{\bm{\varepsilon}}^p} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 233; Simo_Hughes_1998_Computational inelasticity.pdf p. 120_ - -**Work-Hardening Hypothesis Rate Equation** -$$ -\dot{\kappa} = \bm{\sigma} : \dot{\bm{\varepsilon}}^p = (1 - f) \sigma_y \dot{\bar{\varepsilon}}^p -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 232-233; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 267_ - -**Voce Exponential Saturation Isotropic Hardening Law** -$$ -\sigma_y(\bar{\varepsilon}^p) = \sigma_y^0 + (\sigma_y^{\infty} - \sigma_y^0) \left[ 1 - \exp\left( -\frac{\bar{\varepsilon}^p}{e_p^{\infty}} \right) \right] -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 219_ - -**Combined Voce-Linear Isotropic Hardening Law** -$$ -h(\alpha) = \bar{K}_{\infty} - [\bar{K}_{\infty} - \bar{K}_0] \exp(-\delta \alpha) + \bar{H}^{\prime} \alpha -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 184_ - -**Notation:** -\sigma_y, \bar{\sigma}: updated yield stress (flow stress); \sigma_y^0, \bar{K}_0: initial yield stress; \sigma_y^{\infty}, \bar{K}_{\infty}: saturated flow stress; \bar{\varepsilon}^p, \alpha, e_p: equivalent plastic strain; e_p^{\infty}, \delta: saturation strain parameters; H, \bar{H}^{\prime}: linear plastic hardening modulus; \dot{\kappa}: rate of internal isotropic hardening variable; \dot{\bm{\varepsilon}}^p: plastic strain rate tensor. - - -## 3. Algorithmic Implementation - -**Isotropic Hardening Local Newton Return Mapping Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given trial deviatoric stress norm } \|\bm{s}^{\mathrm{tr}}\|, \text{ previous equivalent plastic strain } \bar{\varepsilon}^p_n, \text{ elastic shear modulus } \mu, \text{ and hardening function } \sigma_y(\bar{\varepsilon}^p)$ -\State $\text{Evaluate trial yield function: } f^{\mathrm{tr}} = \|\bm{s}^{\mathrm{tr}}\| - \sqrt{\frac{2}{3}} \sigma_y(\bar{\varepsilon}^p_n)$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\bar{\varepsilon}^p_{n+1} = \bar{\varepsilon}^p_n, \quad \sigma_{y,n+1} = \sigma_y(\bar{\varepsilon}^p_n)$ -\Return $\text{Step is elastic; return trial yield stress}$ -\Else -\EndIf -\While{$|f^{(k)}| > \text{TOL}$} -\State $\bar{\varepsilon}^{p,(k)} = \bar{\varepsilon}^p_n + \sqrt{\frac{2}{3}} \Delta \gamma^{(k)}$ -\State $f^{(k)} = \|\bm{s}^{\mathrm{tr}}\| - 2\mu \Delta \gamma^{(k)} - \sqrt{\frac{2}{3}} \sigma_y\left( \bar{\varepsilon}^{p,(k)} \right)$ -\State $H^{(k)} = \left. \frac{d \sigma_y}{d \bar{\varepsilon}^p} \right|_{\bar{\varepsilon}^{p,(k)}}$ -\State $d\Delta \gamma = \frac{f^{(k)}}{2\mu + \frac{2}{3} H^{(k)}}$ -\State $\Delta \gamma^{(k+1)} = \Delta \gamma^{(k)} + d\Delta \gamma, \quad k = k + 1$ -\EndWhile -\State $\bar{\varepsilon}^p_{n+1} = \bar{\varepsilon}^p_n + \sqrt{\frac{2}{3}} \Delta \gamma, \quad \sigma_{y,n+1} = \sigma_y(\bar{\varepsilon}^p_{n+1})$ -\Return $\text{Return updated equivalent plastic strain } \bar{\varepsilon}^p_{n+1} \text{ and yield stress } \sigma_{y,n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 120-124; Kim_FEA for Elastoplastic Problems.pdf p. 219, 225_ - - -## 4. Known Pitfalls - -- **Unphysical Re-Yielding Under Reverse Cyclic Loading**: Relying exclusively on isotropic hardening for cyclic or reversed loading overpredicts the elastic range upon load reversal by assuming equal yield stress expansion in tension and compression, failing to account for the Bauschinger effect. _(Source: Kim_FEA for Elastoplastic Problems.pdf p. 202, 212; Simo_Hughes_1998_Computational inelasticity.pdf p. 120-121)_ -- **Derivative Discontinuities in Non-Smooth Hardening Functions**: Using piecewise linear or multi-stage empirical curves for \sigma_y(\bar{\varepsilon}^p) without continuous derivatives d\sigma_y/d\bar{\varepsilon}^p causes local Newton-Raphson return-mapping oscillation and degrades global solver convergence. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 122, 184; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 238)_ -- **Confusing Strain-Hardening and Work-Hardening Hypotheses under Softening or Damage**: Assuming equivalence between plastic strain history \bar{\varepsilon}^p and plastic work history \kappa in porous or damaged media introduces errors, because plastic work dissipation is degraded by void volume fraction (1-f). _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 232-233; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 267)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-johnson-cook.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-johnson-cook.md deleted file mode 100644 index a34f8d2..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-johnson-cook.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -id: plasticity-johnson-cook -title: Johnson-Cook Model -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- johnson-cook -- rate-dependent -- thermal-softening -- dynamic -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-isotropic-hardening - type: refines - weight: 0.9 -- to: plasticity-von-mises - type: requires - weight: 1.0 -- to: constit-thermodynamic-framework - type: requires - weight: 0.8 -- to: plasticity-zerilli-armstrong - type: contradicts - weight: 0.5 -- to: plasticity-lode-triaxiality - type: feeds-into - weight: 0.8 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Johnson-Cook Model - -## Summary - -The Johnson-Cook constitutive model formulates rate- and temperature-dependent plastic flow stress using strain hardening, strain rate sensitivity, and thermal softening terms within finite-strain plasticity. - -## 1. Core Concept - -The Johnson-Cook model governs dynamic plasticity by expressing flow stress Y(\bar{\varepsilon}, \dot{\bar{\varepsilon}}, T) through multiplicative contributions accounting for isotropic strain hardening [A + B \bar{\varepsilon}^n], logarithmic strain rate sensitivity [1 + C \ln(\dot{\bar{\varepsilon}} / \dot{\varepsilon}_0)], and thermal softening [1 - \theta^m] based on homologous temperature \theta = (T - T_r) / (T_m - T_r). Integrated within finite-strain multiplicative elastoplasticity (\mathbf{F} = \mathbf{F}^e \mathbf{F}^p) or inelastic equation of state (IEOS) hydrocode frameworks, the Johnson-Cook yield criterion controls plastic dissipation under dynamic impact, shock loading, and thermomechanical deformation. - -## 2. Mathematical Formulation - -**Johnson-Cook Plastic Flow Stress Equation** -$$ -Y(\bar{\varepsilon}, \dot{\bar{\varepsilon}}, T) = \left[ A + B \bar{\varepsilon}^n \right] \left[ 1 + C \ln\left( \frac{\dot{\bar{\varepsilon}}}{\dot{\varepsilon}_0} \right) \right] \left[ 1 - \left( \theta(T) \right)^m \right] -$$ -_Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 198; Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277_ - -**Homologous Temperature Definition** -$$ -\theta(T) = \frac{T - T_r}{T_m - T_r} -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 198_ - -**Finite-Strain Yield Consistency Condition** -$$ -F(\bm{\tau}, \bar{\varepsilon}, T) = \bar{\tau} - Y(\bar{\varepsilon}, \dot{\bar{\varepsilon}}, T) = 0 -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 278, 281_ - -**Plastic Evolution and Temperature Update** -$$ -\dot{\mathbf{F}}^p = \dot{\lambda} \mathbf{R}_e^T \cdot \frac{\partial F}{\partial \bm{\tau}} \cdot \mathbf{R}_e \cdot \mathbf{F}^p, \quad \dot{\bar{\varepsilon}} = \dot{\lambda} -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 276, 278_ - -**Notation:** -Y: equivalent plastic flow stress; A: yield strength parameter; B: strain hardening coefficient; n: strain hardening exponent; C: strain rate sensitivity parameter; \dot{\bar{\varepsilon}}: equivalent plastic strain rate; \dot{\varepsilon}_0: reference strain rate; \theta(T): homologous temperature; T: temperature; T_r: reference room temperature; T_m: melting temperature; m: thermal softening exponent; \bm{\tau}: Kirchhoff stress tensor; \bar{\tau}: equivalent Kirchhoff stress; \bar{\varepsilon}: equivalent plastic strain history variable; \mathbf{F}^p: plastic deformation gradient. - - -## 3. Algorithmic Implementation - -**Johnson-Cook Plasticity Return-Mapping Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: elastic strain } \bm{\varepsilon}^e_n, \text{ equivalent plastic strain } \bar{\varepsilon}_n, \text{ temperature } T_n, \text{ and deformation gradient increment } \mathbf{F}$ -\State $\mathbf{F}^{e,tr} = \mathbf{F} \cdot \mathbf{F}^e_n, \quad \bm{\varepsilon}^{e,tr} = \frac{1}{2} \ln(\mathbf{F}^{e,tr} \cdot \mathbf{F}^{e,tr T}), \quad \bm{\tau}^{tr} = \frac{\partial \Psi}{\partial \bm{\varepsilon}^{e,tr}}$ -\State $\theta_n = \frac{T_n - T_r}{T_m - T_r}, \quad Y_n = [A + B (\bar{\varepsilon}_n)^n]\left[1 + C \ln\left(\frac{\Delta \bar{\varepsilon}}{\Delta t \dot{\varepsilon}_0}\right)\right](1 - \theta_n^m)$ -\State $F^{tr} = \bar{\tau}^{tr} - Y_n$ -\If{$F^{tr} \le 0$} -\State $\bm{\sigma}_{n+1} = J^{-1} \bm{\tau}^{tr}, \quad \bar{\varepsilon}_{n+1} = \bar{\varepsilon}_n, \quad T_{n+1} = T_n$ -\Return $\text{Step is elastic; accept trial state}$ -\Else -\EndIf -\State $\Delta \bar{\varepsilon} = \Delta \lambda, \quad \bar{\varepsilon}_{n+1} = \bar{\varepsilon}_n + \Delta \bar{\varepsilon}$ -\State $\bm{\varepsilon}^e_{n+1} = \bm{\varepsilon}^{e,tr} - \Delta \lambda \mathbf{N}_{n+1}, \quad \bm{\sigma}_{n+1} = J_{n+1}^{-1} \bm{\tau}_{n+1}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ plastic strain } \bar{\varepsilon}_{n+1}, \text{ and temperature } T_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 278, 283-285; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 198_ - - -## 4. Known Pitfalls - -- **Extrapolation to Temperatures Exceeding Material Melting Point**: Evaluating thermal softening (1 - \theta^m) when temperature T approaches or exceeds the melting temperature T_m causes homologous temperature \theta \ge 1, driving flow stress to zero or negative unphysical values unless bounded. _(Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 198; Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277)_ -- **Singularity at Zero Plastic Strain Rates in Logarithmic Rate Sensitivity**: Evaluating the logarithmic rate sensitivity term \ln(\dot{\bar{\varepsilon}} / \dot{\varepsilon}_0) when plastic strain rate approaches zero (\dot{\bar{\varepsilon}} \to 0) produces minus infinity singularities; a reference floor or rate-independent fallback must be enforced. _(Source: Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 198; Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277)_ -- **Thermodynamic Inconsistency in Uncoupled Equation of State Updates**: Evaluating hydrostatic pressure from an uncoupled EOS while using Johnson-Cook flow stress for deviatoric updates violates energy conservation during coupled thermo-mechanical return mapping. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 280, 284)_ - -## References - -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-kinematic-hardening.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-kinematic-hardening.md deleted file mode 100644 index a953ce8..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-kinematic-hardening.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: plasticity-kinematic-hardening -title: Kinematic Hardening (Armstrong-Frederick, Chaboche) -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- hardening -- kinematic-hardening -- bauschinger -- chaboche -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-von-mises - type: refines - weight: 1.0 -- to: plasticity-isotropic-hardening - type: feeds-into - weight: 0.9 -- to: constit-stress-update-architecture - type: requires - weight: 1.0 -- to: constit-thermodynamic-framework - type: requires - weight: 0.8 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Kinematic Hardening (Armstrong-Frederick, Chaboche) - -## Summary - -Kinematic hardening models translate the center of the elastic yield surface in stress space via a back stress tensor, capturing the Bauschinger effect under reverse cyclic plastic loading. - -## 1. Core Concept - -Kinematic hardening accounts for anisotropy induced by plastic deformation history by shifting the origin of the elastic yield surface in stress space through a internal tensor variable known as back stress \bm{\alpha}. Unlike isotropic hardening, which expands the yield surface radius uniformly, kinematic hardening preserves the size and shape of the elastic domain, capturing the Bauschinger effect wherein a material yielding in tension exhibits a reduced yield threshold upon load reversal in compression. In classical J2 plasticity, yield is governed by the shifted stress tensor \bm{\eta} = \bm{s} - \bm{\alpha}, where \bm{s} is deviatoric Cauchy stress. Prager and Ziegler linear kinematic hardening rules specify rate evolution \dot{\bm{\alpha}} = \frac{2}{3} H_{\mathrm{kin}} \dot{\bm{\varepsilon}}^p. In combined isotropic/kinematic models, a scalar weighting parameter \beta \in [1] partitions total hardening modulus H into isotropic and kinematic back stress contributions. - -## 2. Mathematical Formulation - -**Shifted Deviatoric Stress Tensor** -$$ -\bm{\eta} = \bm{s} - \bm{\alpha} -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 218, 222; Simo_Hughes_1998_Computational inelasticity.pdf p. 120, 124_ - -**Von Mises Yield Function with Kinematic Hardening** -$$ -f(\bm{s}, \bm{\alpha}, \sigma_y) = \|\bm{s} - \bm{\alpha}\| - \sqrt{\frac{2}{3}} \sigma_y = 0 -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 222, 228; Simo_Hughes_1998_Computational inelasticity.pdf p. 120_ - -**Linear Kinematic Hardening Back Stress Evolution** -$$ -\dot{\bm{\alpha}} = \frac{2}{3} H_{\mathrm{kin}} \dot{\bm{\varepsilon}}^p = \frac{2}{3} H_{\mathrm{kin}} \dot{\gamma} \mathbf{N}, \quad \mathbf{N} = \frac{\bm{\eta}}{\|\bm{\eta}\|} -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 228; Simo_Hughes_1998_Computational inelasticity.pdf p. 120, 124_ - -**Combined Isotropic-Kinematic Hardening Evolution** -$$ -\dot{\bm{\alpha}} = \frac{2}{3} \beta H \dot{\gamma} \mathbf{N}, \quad \dot{\sigma}_y = \sqrt{\frac{2}{3}} (1 - \beta) H \dot{\gamma} -$$ -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 222, 228; Simo_Hughes_1998_Computational inelasticity.pdf p. 120, 184_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; \bm{s}: deviatoric Cauchy stress tensor; \bm{\alpha}: back stress tensor; \bm{\eta}: shifted stress tensor (\bm{s} - \bm{\alpha}); f: yield function; \sigma_y: yield stress radius; H_{\mathrm{kin}}, H: kinematic and total plastic hardening moduli; \beta: combined hardening parameter (0 \le \beta \le 1); \mathbf{N}: unit yield surface normal vector; \dot{\gamma}, \Delta \gamma: plastic consistency parameter rate and increment; \bm{\varepsilon}^p: plastic strain tensor. - - -## 3. Algorithmic Implementation - -**J2 Kinematic and Combined Hardening Return-Mapping Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: stress } \bm{s}_n, \text{ back stress } \bm{\alpha}_n, \text{ equivalent plastic strain } \bar{\varepsilon}^p_n, \text{ strain increment } \Delta \bm{\varepsilon}, \text{ and material parameters } \mu, H, \beta, \sigma_y^0$ -\State $\bm{s}^{\mathrm{tr}} = \bm{s}_n + 2\mu \operatorname{dev}(\Delta \bm{\varepsilon}), \quad \bm{\alpha}^{\mathrm{tr}} = \bm{\alpha}_n, \quad \bm{\eta}^{\mathrm{tr}} = \bm{s}^{\mathrm{tr}} - \bm{\alpha}^{\mathrm{tr}}$ -\State $\sigma_y^{\mathrm{tr}} = \sigma_y^0 + (1 - \beta) H \bar{\varepsilon}^p_n, \quad f^{\mathrm{tr}} = \|\bm{\eta}^{\mathrm{tr}}\| - \sqrt{\frac{2}{3}} \sigma_y^{\mathrm{tr}}$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\bm{s}_{n+1} = \bm{s}^{\mathrm{tr}}, \quad \bm{\alpha}_{n+1} = \bm{\alpha}^{\mathrm{tr}}, \quad \bar{\varepsilon}^p_{n+1} = \bar{\varepsilon}^p_n$ -\Return $\text{Step is elastic; accept trial state}$ -\Else -\EndIf -\State $\bm{s}_{n+1} = \bm{s}^{\mathrm{tr}} - 2\mu \Delta \gamma \mathbf{N}, \quad \bm{\alpha}_{n+1} = \bm{\alpha}_n + \frac{2}{3} \beta H \Delta \gamma \mathbf{N}$ -\State $\bar{\varepsilon}^p_{n+1} = \bar{\varepsilon}^p_n + \sqrt{\frac{2}{3}} \Delta \gamma, \quad \bm{\sigma}_{n+1} = \bm{s}_{n+1} + \frac{1}{3} \mathrm{tr}(\bm{\sigma}^{\mathrm{tr}}) \mathbf{I}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ back stress } \bm{\alpha}_{n+1}, \text{ and plastic strain } \bar{\varepsilon}^p_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Kim_FEA for Elastoplastic Problems.pdf p. 218-222, 228-230; Simo_Hughes_1998_Computational inelasticity.pdf p. 120-125_ - - -## 4. Known Pitfalls - -- **Inability to Model Yield Surface Expansion in Pure Kinematic Hardening**: Using pure kinematic hardening (\beta = 1) translates the yield surface center without allowing the elastic domain size to expand, underpredicting flow stress growth during monotonic hardening regimes. _(Source: Kim_FEA for Elastoplastic Problems.pdf p. 217, 222; Simo_Hughes_1998_Computational inelasticity.pdf p. 120-121)_ -- **Spurious Stress Oscillations in Finite Rotation Without Objective Back Stress Integration**: Evaluating back stress rate equations \dot{\bm{\alpha}} in large-deformation analysis without co-rotational rate objective integration (e.g. Jaumann or Green-Naghdi rates) introduces artificial stress oscillations during rigid body rotation. _(Source: Kim_FEA for Elastoplastic Problems.pdf p. 244-245; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 412-414; Simo_Hughes_1998_Computational inelasticity.pdf p. 316)_ -- **Division by Zero at Zero Shifted Stress Norm**: Evaluating unit normal vector \mathbf{N} = \bm{\eta}^{\mathrm{tr}} / \|\bm{\eta}^{\mathrm{tr}}\| when trial shifted stress vanishes (\bm{s}^{\mathrm{tr}} = \bm{\alpha}_n) leads to floating-point division by zero; elastic step logic must be checked prior to normal calculation. _(Source: Kim_FEA for Elastoplastic Problems.pdf p. 222, 228; Simo_Hughes_1998_Computational inelasticity.pdf p. 124)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-lode-triaxiality.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-lode-triaxiality.md deleted file mode 100644 index b57c7bf..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-lode-triaxiality.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: plasticity-lode-triaxiality -title: Stress Triaxiality & Lode Angle in Plasticity -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- triaxiality -- lode-angle -- ductile-fracture -- bai-wierzbicki -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-invariants - type: requires - weight: 1.0 -- to: plasticity-von-mises - type: refines - weight: 0.6 -- to: damage-continuum-framework - type: feeds-into - weight: 0.9 -- to: damage-gtn-void-evolution - type: feeds-into - weight: 0.8 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Stress Triaxiality & Lode Angle in Plasticity - -## Summary - -Stress triaxiality and Lode angle parameterize three-dimensional stress states, governing void evolution, yield surface shape, and Lode-dependent ductile material failure. - -## 1. Core Concept - -In continuum mechanics and plasticity, characterising three-dimensional stress states requires three scalar stress invariants beyond hydrostatic pressure alone: hydrostatic stress \sigma_m = \frac{1}{3}\mathrm{tr}(\bm{\sigma}) (or pressure p = -\sigma_m), von Mises equivalent stress \sigma_e = \sqrt{3 J_2}, and the third deviatoric stress invariant J_3 = \det(\bm{s}). Stress triaxiality \eta = \sigma_m / \sigma_e governs volumetric void growth and compaction, while Lode angle \theta = \frac{1}{3} \arccos\left( \frac{3\sqrt{3}}{2} \frac{J_3}{J_2^{3/2}} \right) measures the normalized third invariant, distinguishing between pure shear, axisymmetric extension, and axisymmetric compression stress states. - -## 2. Mathematical Formulation - -**Stress Triaxiality Ratio** -$$ -\eta = \frac{\sigma_m}{\sigma_e} = \frac{\mathrm{tr}(\bm{\sigma})}{3 \sqrt{3 J_2}} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 19; Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 104468_ - -**Lode Angle and Third Invariant Relation** -$$ -\theta = \frac{1}{3} \arccos\left( \frac{3\sqrt{3}}{2} \frac{J_3}{J_2^{3/2}} \right) -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 226, 261-262; Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 104468_ - -**Lode-Dependent Mohr-Coulomb Yield Surface** -$$ -f(\bm{s}, p, \theta) = \sqrt{J_2} \cos\theta - \left( \frac{2}{\sqrt{3}}\sqrt{J_2} - p \right) \sin\phi - c \cos\phi = 0 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 261-262_ - -**Normalized Lode Stress Parameter** -$$ -L = \frac{2\sigma_2 - \sigma_1 - \sigma_3}{\sigma_1 - \sigma_3} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 226; Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 104468_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; \bm{s}: deviatoric stress tensor; \sigma_m: mean hydrostatic stress; p: hydrostatic pressure (-1/3 tr(\bm{\sigma})); \sigma_e: von Mises equivalent stress; J_2: second invariant of deviatoric stress; J_3: third invariant of deviatoric stress; \eta: stress triaxiality ratio; \theta: Lode angle; L: normalized Lode parameter; \phi: friction angle; c: cohesion. - - -## 3. Algorithmic Implementation - -**Lode Angle and Stress Triaxiality Computation Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given Cauchy stress tensor } \bm{\sigma}$ -\State $p = -\frac{1}{3} \mathrm{tr}(\bm{\sigma}), \quad \sigma_m = \frac{1}{3} \mathrm{tr}(\bm{\sigma})$ -\State $\bm{s} = \bm{\sigma} - \sigma_m \mathbf{I}$ -\State $J_2 = \frac{1}{2} \bm{s} : \bm{s}, \quad \sigma_e = \sqrt{3 J_2}$ -\If{$J_2 \le \text{TOL}$} -\State $\eta = 0, \quad \theta = 0, \quad L = 0$ -\Return $\text{Hydrostatic stress state; return zero deviatoric invariants}$ -\Else -\EndIf -\State $\eta = \frac{\sigma_m}{\sigma_e}$ -\State $\xi_3 = \frac{3\sqrt{3}}{2} \frac{J_3}{J_2^{3/2}}$ -\State $\xi_{clamped} = \max\left(-1, \min\left(1, \xi_3\right)\right)$ -\State $\theta = \frac{1}{3} \arccos\left(\xi_{clamped}\right)$ -\Return $\text{Return stress triaxiality } \eta, \text{ Lode angle } \theta, \text{ and invariants } J_2, J_3$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 19, 226, 261-262_ - - -## 4. Known Pitfalls - -- **Arccosine Argument Domain Violations from Floating-Point Roundoff**: Evaluating arccosine functions when numerical errors push the argument \xi_3 slightly outside [-1, 1] causes NaN domain exceptions unless clamped prior to evaluation. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 261-262)_ -- **Division by Zero at Hydrostatic Stress States**: Evaluating stress triaxiality \eta = \sigma_m / \sqrt{3 J_2} or Lode angle when J_2 \to 0 produces floating-point division by zero; hydrostatic check thresholds must be enforced. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 261-262)_ -- **Neglecting Lode Angle Dependence in Ductile Void Coalescence Models**: Assuming void evolution depends purely on stress triaxiality \eta without accounting for Lode angle \theta mispredicts failure mode transitions between tensile internal necking and localized shear band coalescence. _(Source: Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf p. 104468; Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf p. 011001)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Torki and Benzerga - 2021 - Ductile Fracture in Plane Stress.pdf -- Torki et al. - 2021 - An analysis of Lode effects in ductile failure.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-peirce-rate-tangent.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-peirce-rate-tangent.md deleted file mode 100644 index 6d9bea4..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-peirce-rate-tangent.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -id: plasticity-peirce-rate-tangent -title: Peirce-Shih-Needleman Rate Tangent Method -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- viscoplasticity -- rate-tangent -- forward-gradient -- peirce-needleman -- crystal-plasticity -status: tentative -confidence: 0.85 -source: hybrid -confidence_floor: 0.7 -edges: -- to: plasticity-von-mises - type: refines - weight: 0.8 - note: 'Rate-dependent generalisation of J2: replaces the consistency condition with an explicit viscoplastic flow rate integrated - by a forward gradient' -- to: plasticity-perzyna - type: contradicts - weight: 0.5 - note: Same viscoplastic flow law, different integration — PSN uses a non-iterative forward-gradient tangent; Perzyna requires - an inner Newton on the overstress residual -- to: plasticity-duvaut-lions - type: feeds-into - weight: 0.6 - note: Duvaut-Lions borrows the Peirce tangent-modulus relation for its consistent tangent; PSN is the original source of - that rate-tangent linearisation -- to: constit-stress-update-architecture - type: requires - weight: 1.0 - note: Same elastic-predictor / plastic-corrector scaffolding; the corrector is a single linear solve rather than a return-mapping - Newton loop -- to: plasticity-consistent-tangent-general - type: feeds-into - weight: 0.7 - note: Supplies a rate-dependent algorithmic tangent that smoothly limits to the rate-independent consistent tangent as m - -> 0 -load_with: -- plasticity-perzyna -- plasticity-duvaut-lions -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Peirce-Shih-Needleman Rate Tangent Method - -## Summary - -The Peirce-Shih-Needleman (PSN, 1984) rate-tangent method integrates rate-dependent (viscoplastic) constitutive laws with a non-iterative forward-gradient scheme. The plastic strain rate is an EXPLICIT function of state, $\dot{\bar\varepsilon}^p=h(\sigma_e,\bar\varepsilon^p)$ — typically the power law $\dot{\bar\varepsilon}^p=\dot\varepsilon_0(\sigma_e/g(\bar\varepsilon^p))^{1/m}$ — so there is no yield surface and no KKT consistency to enforce. The increment is sampled at $t+\theta\Delta t$: $\Delta\bar\varepsilon^p=\Delta t[(1-\theta)\dot{\bar\varepsilon}^p_t+\theta\dot{\bar\varepsilon}^p_{t+\Delta t}]$, and $\dot{\bar\varepsilon}^p_{t+\Delta t}$ is replaced by its first-order Taylor expansion (the "tangent" of the rate) about the current state. Eliminating $\Delta\bar\varepsilon^p$ gives a closed-form, rate-dependent TANGENT MODULUS $\mathbb{L}^{\mathrm{tan}}$ plus an additive relaxation/creep term — a stress update with NO local Newton iteration. The forward-gradient parameter $\theta\ge 1/2$ makes the scheme unconditionally stable, permitting time steps far larger than the viscoplastic relaxation time (where explicit forward Euler, $\theta=0$, would be conditionally stable and require tiny steps). The method is designed so that as the rate-sensitivity $m\to 0$, $\mathbb{L}^{\mathrm{tan}}$ smoothly recovers the rate-independent elastoplastic consistent tangent — one algorithm spans the rate-independent-to-strongly-rate-dependent spectrum. It is the workhorse integrator for rate-dependent crystal plasticity, where the forward gradient removes the active-slip-set ambiguity of the rate-independent formulation. - -## 1. Core Concept - -Rate-independent plasticity enforces $f\le 0$, $\dot\gamma\,f=0$ (KKT) and solves a return mapping; rate-dependent (viscoplastic) plasticity instead postulates that the plastic flow rate is a smooth, single-valued function of the current stress and internal state, $\dot{\bar\varepsilon}^p=h(\sigma_e,\bar\varepsilon^p)$, so stress can lie OUTSIDE the quasi-static flow surface (overstress) and the flow magnitude is determined directly — no consistency condition, no active-set decision. The numerical challenge is that this rate law is stiff: for low rate-sensitivity (small $m$) a tiny change in stress produces a large change in plastic rate, so an explicit forward-Euler update needs prohibitively small time steps. PSN's insight is to evaluate the plastic increment with a generalised-midpoint (forward-gradient) rule, $\Delta\bar\varepsilon^p=\Delta t[(1-\theta)\dot{\bar\varepsilon}^p_t+\theta\dot{\bar\varepsilon}^p_{t+\Delta t}]$, and to LINEARISE the unknown end-of-step rate $\dot{\bar\varepsilon}^p_{t+\Delta t}$ rather than solve for it implicitly. The linearisation introduces the partial derivatives $h_\sigma=\partial\dot{\bar\varepsilon}^p/\partial\sigma_e$ and $h_\varepsilon=\partial\dot{\bar\varepsilon}^p/\partial\bar\varepsilon^p$; combined with the elastic relation between stress and plastic-strain increments, $\Delta\bar\varepsilon^p$ is obtained from a single scalar division, and the stress update collapses to $\Delta\boldsymbol{\sigma}=\mathbb{L}^{\mathrm{tan}}\colon\Delta\boldsymbol{\varepsilon}-\Delta\boldsymbol{\sigma}^{\mathrm{relax}}$. The tangent modulus $\mathbb{L}^{\mathrm{tan}}$ has the familiar rank-one-down structure of the elastoplastic tangent, but its plastic-correction strength is governed by $\theta\Delta t\,h_\sigma$ instead of a hardening modulus — and crucially it limits continuously to the rate-independent consistent tangent as $m\to 0$. With $\theta\ge 1/2$ the implicit weighting damps the stiff response and gives unconditional linear stability, so the same code handles quasi-static ($\Delta t\gg$ relaxation time) and dynamic loading without switching algorithms. This is why PSN is the standard integrator in rate-dependent crystal plasticity (forward gradient on each slip rate $\dot\gamma^\alpha$) and a common regulariser for shear-band and localisation problems. - -## 2. Mathematical Formulation - -**Viscoplastic flow rate (power law)** -$$ -\dot{\bar\varepsilon}^p = h(\sigma_e,\bar\varepsilon^p) -= \dot\varepsilon_0\!\left[\frac{\sigma_e}{g(\bar\varepsilon^p)}\right]^{1/m}, -\qquad -\dot{\boldsymbol{\varepsilon}}^p = \dot{\bar\varepsilon}^p\,\mathbf{P} -$$ - -**Forward-gradient (theta-rule) plastic increment** -$$ -\Delta\bar\varepsilon^p = \Delta t\left[(1-\theta)\,\dot{\bar\varepsilon}^p_t + \theta\,\dot{\bar\varepsilon}^p_{t+\Delta t}\right], -\qquad \theta\in[0,1] -$$ - -**Rate tangent (first-order linearisation of the end-of-step rate)** -$$ -\dot{\bar\varepsilon}^p_{t+\Delta t} \approx \dot{\bar\varepsilon}^p_t -+ h_\sigma\,\Delta\sigma_e + h_\varepsilon\,\Delta\bar\varepsilon^p, -\qquad -h_\sigma=\frac{\partial\dot{\bar\varepsilon}^p}{\partial\sigma_e},\;\; -h_\varepsilon=\frac{\partial\dot{\bar\varepsilon}^p}{\partial\bar\varepsilon^p} -$$ - -**Power-law derivatives** -$$ -h_\sigma = \frac{\dot{\bar\varepsilon}^p}{m\,\sigma_e} > 0, -\qquad -h_\varepsilon = -\,\frac{\dot{\bar\varepsilon}^p}{m}\,\frac{g'(\bar\varepsilon^p)}{g(\bar\varepsilon^p)} \le 0 -$$ - -**Elastic stress/Mises-stress increment relation** -$$ -\Delta\boldsymbol{\sigma} = \mathbb{C}^e\colon\Delta\boldsymbol{\varepsilon} - \Delta\bar\varepsilon^p\,(\mathbb{C}^e\colon\mathbf{P}), -\qquad -\Delta\sigma_e = \mathbf{P}\colon\mathbb{C}^e\colon\Delta\boldsymbol{\varepsilon} - a\,\Delta\bar\varepsilon^p -$$ - -**Closed-form plastic increment** -$$ -\Delta\bar\varepsilon^p = -\frac{\Delta t\,\dot{\bar\varepsilon}^p_t + \theta\Delta t\,h_\sigma\,(\mathbf{P}\colon\mathbb{C}^e\colon\Delta\boldsymbol{\varepsilon})}{D}, -\qquad -D = 1 - \theta\Delta t\,h_\varepsilon + \theta\Delta t\,h_\sigma\,a -$$ - -**Rate-tangent stress update** -$$ -\Delta\boldsymbol{\sigma} = \mathbb{L}^{\mathrm{tan}}\colon\Delta\boldsymbol{\varepsilon} - \Delta\boldsymbol{\sigma}^{\mathrm{relax}} -$$ - -**Rate tangent modulus** -$$ -\mathbb{L}^{\mathrm{tan}} = \mathbb{C}^e -- \frac{\theta\Delta t\,h_\sigma}{D}\,(\mathbb{C}^e\colon\mathbf{P})\otimes(\mathbf{P}\colon\mathbb{C}^e) -$$ - -**Relaxation (creep) term** -$$ -\Delta\boldsymbol{\sigma}^{\mathrm{relax}} = \frac{\Delta t\,\dot{\bar\varepsilon}^p_t}{D}\,(\mathbb{C}^e\colon\mathbf{P}) -$$ - -**Rate-independent limit (m -> 0)** -$$ -\frac{\theta\Delta t\,h_\sigma}{D} \;\xrightarrow{\,m\to 0\,}\; \frac{1}{a + h}, -\qquad -\mathbb{L}^{\mathrm{tan}} \to \mathbb{C}^e - \frac{(\mathbb{C}^e\colon\mathbf{P})\otimes(\mathbf{P}\colon\mathbb{C}^e)}{\mathbf{P}\colon\mathbb{C}^e\colon\mathbf{P} + h} -$$ - -**Linear stability of the forward gradient** -$$ -\theta \ge \tfrac12:\ \text{unconditionally stable};\qquad -\theta < \tfrac12:\ \Delta t \lesssim \frac{1}{(1-2\theta)\,a\,h_\sigma} -$$ - -**Crystal-plasticity form (per slip system)** -$$ -\dot\gamma^\alpha = \dot\gamma_0\left|\frac{\tau^\alpha}{g^\alpha}\right|^{1/m}\!\operatorname{sgn}(\tau^\alpha), -\qquad -\Delta\gamma^\alpha = \Delta t\left[(1-\theta)\dot\gamma^\alpha_t + \theta\dot\gamma^\alpha_{t+\Delta t}\right] -$$ - -**Notation:** -{'\\dot{\\bar\\varepsilon}^p': 'Effective viscoplastic strain rate (explicit function of state)', '\\sigma_e': 'Mises effective stress, $\\sqrt{\\tfrac32\\mathbf{s}\\colon\\mathbf{s}}$', 'g(\\bar\\varepsilon^p)': "Flow strength / hardening function; $h=g'$ is the hardening modulus", 'm': 'Strain-rate sensitivity exponent ($m\\to 0$ rate-independent, $m=1$ linear viscous)', '\\dot\\varepsilon_0': 'Reference strain rate', '\\theta': 'Forward-gradient / time-integration parameter in $[0,1]$', '\\mathbf{P}': 'Mises stress gradient / flow direction, $\\tfrac{3}{2}\\mathbf{s}/\\sigma_e$', 'h_\\sigma': '$\\partial\\dot{\\bar\\varepsilon}^p/\\partial\\sigma_e$ (rate sensitivity to stress)', 'h_\\varepsilon': '$\\partial\\dot{\\bar\\varepsilon}^p/\\partial\\bar\\varepsilon^p$ (rate sensitivity to hardening)', 'a': '$\\mathbf{P}\\colon\\mathbb{C}^e\\colon\\mathbf{P}=3\\mu$ for isotropic elasticity', 'D': 'Forward-gradient denominator $1-\\theta\\Delta t\\,h_\\varepsilon+\\theta\\Delta t\\,h_\\sigma a$', '\\mathbb{L}^{\\mathrm{tan}}': 'Rate tangent modulus', '\\dot\\gamma^\\alpha': 'Slip rate on system $\\alpha$ (crystal plasticity form)'} - - -## 3. Algorithmic Implementation - -**PSN Rate-Tangent Stress Update (J2)** -$$ -\begin{algorithmic} -\State State \text{input} \colon \boldsymbol{\sigma}_n,\bar\varepsilon^p_n,\Delta\boldsymbol{\varepsilon},\mathbb{C}^e,\dot\varepsilon_0,m,g(\cdot),g'(\cdot),\theta,\Delta t -\State State \boldsymbol{\sigma}^{\mathrm{trial}} \gets \boldsymbol{\sigma}_n + \mathbb{C}^e\colon\Delta\boldsymbol{\varepsilon},\quad \mathbf{s}\gets\operatorname{dev}\boldsymbol{\sigma}^{\mathrm{trial}} -\State State \sigma_e \gets \sqrt{\tfrac32\,\mathbf{s}\colon\mathbf{s}},\quad \mathbf{P}\gets \tfrac{3}{2}\,\mathbf{s}/\sigma_e -\State State \dot{\bar\varepsilon}^p_t \gets \dot\varepsilon_0\,(\sigma_e/g(\bar\varepsilon^p_n))^{1/m} -\State State h_\sigma \gets \dot{\bar\varepsilon}^p_t/(m\,\sigma_e),\quad h_\varepsilon \gets -\,\dot{\bar\varepsilon}^p_t\,g'(\bar\varepsilon^p_n)/(m\,g(\bar\varepsilon^p_n)) -\State State a \gets \mathbf{P}\colon\mathbb{C}^e\colon\mathbf{P}\;(=3\mu),\quad D \gets 1 - \theta\Delta t\,h_\varepsilon + \theta\Delta t\,h_\sigma\,a -\State State \Delta\bar\varepsilon^p \gets [\Delta t\,\dot{\bar\varepsilon}^p_t + \theta\Delta t\,h_\sigma\,(\mathbf{P}\colon\mathbb{C}^e\colon\Delta\boldsymbol{\varepsilon})]/D -\State State \boldsymbol{\sigma}_{n+1} \gets \boldsymbol{\sigma}^{\mathrm{trial}} - \Delta\bar\varepsilon^p\,(\mathbb{C}^e\colon\mathbf{P}) -\State State \bar\varepsilon^p_{n+1} \gets \bar\varepsilon^p_n + \Delta\bar\varepsilon^p -\State State \mathbb{L}^{\mathrm{tan}} \gets \mathbb{C}^e - (\theta\Delta t\,h_\sigma/D)\,(\mathbb{C}^e\colon\mathbf{P})\otimes(\mathbf{P}\colon\mathbb{C}^e) -\State Return \boldsymbol{\sigma}_{n+1},\bar\varepsilon^p_{n+1},\mathbb{L}^{\mathrm{tan}} -\end{algorithmic} -$$ -Taichi Mapping: Per-Gauss-point `@ti.func`, NON-iterative: one evaluation of the rate and its two derivatives, one scalar denominator $D$, one rank-one tangent update. Far cheaper than implicit Perzyna (no inner Newton). Guard the elastic branch with $\sigma_e>\sigma_{\min}$ to avoid divide-by-zero in $\mathbf{P}$ and $h_\sigma$ (when $\sigma_e\to 0$ set $\dot{\bar\varepsilon}^p=0$, $\Delta\bar\varepsilon^p=0$). Use $\theta\in[0.5,1]$ for unconditional stability; $\theta=0.5$ is second-order accurate but lightly damped, $\theta=1$ is first-order and strongly damped (robust for very stiff $m$). The whole update is branch-light and vectorises well on GPU. - -**Compute Rate-Tangent Modulus (standalone)** -$$ -\begin{algorithmic} -\State State \text{input} \colon \mathbf{P},\mathbb{C}^e,h_\sigma,h_\varepsilon,a,\theta,\Delta t -\State State D \gets 1 - \theta\Delta t\,h_\varepsilon + \theta\Delta t\,h_\sigma\,a -\State State \mathbb{L}^{\mathrm{tan}} \gets \mathbb{C}^e - (\theta\Delta t\,h_\sigma/D)\,(\mathbb{C}^e\colon\mathbf{P})\otimes(\mathbf{P}\colon\mathbb{C}^e) -\State Return \mathbb{L}^{\mathrm{tan}} -\end{algorithmic} -$$ -Taichi Mapping: Consistent tangent for the global Newton solve. As $m\to 0$ the factor $\theta\Delta t\,h_\sigma/D\to 1/(a+h)$ and $\mathbb{L}^{\mathrm{tan}}$ becomes the rate-independent J2 consistent tangent — so the SAME assembly path serves quasi-static and dynamic regimes. The tangent is symmetric for associated J2 (rank-one symmetric correction); reuse $\mathbb{C}^e\colon\mathbf{P}$ from the stress update to avoid recomputing the double contraction. - -**Forward-Gradient Crystal-Plasticity Slip Update** -$$ -\begin{algorithmic} -\State State \text{input} \colon \{\tau^\alpha\},\{g^\alpha\},\dot\gamma_0,m,\theta,\Delta t,\{\mathbf{m}^\alpha\otimes\mathbf{n}^\alpha\} -\State For \alpha = 1,\ldots,N_{\mathrm{slip}} -\State State \dot\gamma^\alpha_t \gets \dot\gamma_0\,|\tau^\alpha/g^\alpha|^{1/m}\operatorname{sgn}(\tau^\alpha) -\State State \frac{\partial\dot\gamma^\alpha}{\partial\tau^\beta} \gets \frac{\dot\gamma_0}{m\,g^\alpha}|\tau^\alpha/g^\alpha|^{1/m-1}\,\delta^{\alpha\beta} -\State EndFor -\State State \text{assemble } \Delta\gamma^\alpha = \Delta t[(1-\theta)\dot\gamma^\alpha_t + \theta\dot\gamma^\alpha_{t+\Delta t}]\,\text{with the linearised}\,\dot\gamma^\alpha_{t+\Delta t} -\State State \text{solve the } N_{\mathrm{slip}}\times N_{\mathrm{slip}}\,\text{linear system for}\,\{\Delta\gamma^\alpha\} -\State State \Delta\boldsymbol{\varepsilon}^p \gets \sum_\alpha \Delta\gamma^\alpha\,\operatorname{sym}(\mathbf{m}^\alpha\otimes\mathbf{n}^\alpha) -\State Return \Delta\boldsymbol{\varepsilon}^p,\{\Delta\gamma^\alpha\} -\end{algorithmic} -$$ -Taichi Mapping: The forward gradient turns the otherwise stiff, non-unique rate-independent slip problem into one well-conditioned linear solve of size $N_{\mathrm{slip}}$ ($12$ for FCC, $24/48$ for BCC). This is the canonical PSN application (Peirce, Asaro & Needleman 1983). Build the slip-interaction Jacobian once per increment; with $\theta\ge 1/2$ the step is stable even when individual slip systems are very rate-sensitive. For small $m$ (near rate-independent) reduce $\Delta t$ or raise $\theta$ to keep the linear system well-conditioned. - - -## 4. Known Pitfalls - -- **Forward Euler (theta = 0) is only conditionally stable**: With $\theta=0$ the scheme is explicit forward Euler and the stable step is bounded by $\Delta t\lesssim 1/(a\,h_\sigma)$ — for low rate-sensitivity (small $m$, large $h_\sigma$) this is prohibitively small. Always use $\theta\ge 1/2$ for unconditional linear stability; the original PSN paper recommends $\theta\in[0.5,1]$. Reserve $\theta=0$ only for explicit-dynamics codes where $\Delta t$ is already tiny for other reasons. -- **Rate-independent limit makes the derivatives blow up**: As $m\to 0$ both $h_\sigma=\dot{\bar\varepsilon}^p/(m\sigma_e)$ and $|h_\varepsilon|$ diverge like $1/m$. The TANGENT is well-behaved (the ratio $\theta\Delta t\,h_\sigma/D\to 1/(a+h)$ is finite) but computing $h_\sigma$ literally overflows in floating point. Reformulate in terms of the bounded ratio $\theta\Delta t\,h_\sigma/D$, or floor the exponent at $m\ge m_{\min}\sim 10^{-3}$, or switch to a rate-independent return mapping below $m_{\min}$. -- **theta trades accuracy against numerical damping**: $\theta=1/2$ (midpoint) is second-order accurate but lightly damped — it can produce stress oscillations for stiff problems or large steps. $\theta=1$ (backward) is only first-order but strongly damped and robust. Pick $\theta$ per regime: $0.5$ for smooth quasi-static loading where accuracy matters, closer to $1$ for impact / very rate-sensitive materials. Document the choice; results depend on it. -- **Single linearisation is inaccurate for large strain increments**: The forward gradient is a FIRST-ORDER Taylor expansion of the rate about the start-of-step state. If $\Delta\sigma_e$ over the step is a large fraction of $\sigma_e$ (large $\Delta t$ or sharp loading), the single linearisation is inaccurate and the flow rule is not satisfied to tight tolerance. Sub-step the increment, reduce $\Delta t$, or iterate the rate-tangent update (re-linearise about the updated state) when accuracy is critical. -- **Not a fully implicit return mapping**: PSN is SEMI-explicit: it satisfies a linearised flow rule, not the exact rate equation, each step. Do not expect machine-precision satisfaction of $\dot{\bar\varepsilon}^p=h(\sigma_e,\bar\varepsilon^p)$ at end of step the way an implicit Perzyna return mapping delivers. For tight per-step tolerance use implicit Perzyna (inner Newton) or iterate the rate tangent; PSN trades that for speed and robustness across rate regimes. -- **Omitting the relaxation (creep) term**: The stress update has TWO parts: $\mathbb{L}^{\mathrm{tan}}\colon\Delta\boldsymbol{\varepsilon}$ and the strain-independent relaxation term $\Delta t\,\dot{\bar\varepsilon}^p_t/D\,(\mathbb{C}^e\colon\mathbf{P})$. Forgetting the second term means stress does not relax under a strain hold ($\Delta\boldsymbol{\varepsilon}=0$), so creep and stress-relaxation responses are lost while monotonic loading may still look plausible — a subtle bug. Always include it. -- **Crystal plasticity: stiff/ill-conditioned slip Jacobian at small m**: For strongly rate-dependent crystal plasticity (small $m$), the $N_{\mathrm{slip}}\times N_{\mathrm{slip}}$ forward-gradient Jacobian becomes stiff and can be ill-conditioned, especially with many near-active systems. Raise $\theta$ toward $1$, reduce $\Delta t$, or add latent-hardening regularisation. The forward gradient still beats rate-independent active-set search (which is non-unique for $\ge 5$ active systems), but it is not unconditionally cheap. -- **sigma_0 / reference-rate and exponent conventions**: Two exponent conventions coexist: $\dot{\bar\varepsilon}^p\propto(\sigma_e/g)^{1/m}$ (rate-sensitivity $m$, used here and in PSN/crystal-plasticity) versus $\propto(\sigma_e/g)^{n}$ with $n=1/m$ (creep-exponent form). Mixing them inverts the rate dependence. State which exponent is the rate-sensitivity and which is its reciprocal, and keep $\dot\varepsilon_0$, $g$ consistent with the calibration data. - -## References - -- Peirce, Shih & Needleman (1984) — A tangent modulus method for rate dependent solids, Computers & Structures 18(5):875-887 (the rate-tangent / forward-gradient method) -- Peirce, Asaro & Needleman (1983) — Material rate dependence and localized deformation in crystalline solids, Acta Metall. 31:1951-1976 (forward gradient for rate-dependent crystal plasticity) -- Zhang (1995) — Explicit consistent tangent moduli with a return mapping algorithm for elastoplasticity (companion explicit-tangent approach) -- Zabaras & Arif (1992) — A family of integration algorithms for constitutive equations in finite-deformation elasto-viscoplasticity (generalised-midpoint integrators) -- Simo & Hughes (1998) — Computational Inelasticity (viscoplastic integration, generalized-midpoint stability context) diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-perzyna.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-perzyna.md deleted file mode 100644 index 2cafb0d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-perzyna.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: plasticity-perzyna -title: Perzyna Viscoplasticity -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- viscoplasticity -- perzyna -- rate-dependent -- regularisation -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-von-mises - type: refines - weight: 0.9 -- to: constit-stress-update-architecture - type: requires - weight: 1.0 -- to: plasticity-duvaut-lions - type: contradicts - weight: 0.5 -- to: pf-ductile-plasticity-coupling - type: feeds-into - weight: 0.6 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Perzyna Viscoplasticity - -## Summary - -Perzyna viscoplasticity formulates rate-dependent inelastic deformation using an overstress function that allows stress states to exceed the yield surface. - -## 1. Core Concept - -Perzyna viscoplasticity extends classical rate-independent plasticity to rate-dependent regimes by replacing discrete Kuhn-Tucker yield consistency with a continuous overstress rate law. In the Perzyna formulation, plastic flow occurs whenever the yield function f(\bm{\sigma}, \bm{q}) > 0, with the viscoplastic strain rate \dot{\bm{\varepsilon}}^{vp} governed by a monotonic function of the overstress \Phi(f) scaled by a fluid viscosity parameter \eta. Under dynamic strain softening, viscoplasticity regularizes ill-posed boundary value problems, restoring hyperbolicity in transient initial-value problems and preventing mesh sensitivity. - -## 2. Mathematical Formulation - -**Perzyna Viscoplastic Flow Rule** -$$ -\dot{\bm{\varepsilon}}^{vp} = \frac{\langle \Phi(f(\bm{\sigma}, \bm{q})) \rangle}{\eta} \frac{\partial f}{\partial \bm{\sigma}} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 109; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 293_ - -**Macaulay Bracket Overstress Function Definition** -$$ -\langle \Phi(f) \rangle = \frac{\Phi(f) + |\Phi(f)|}{2} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 109_ - -**Implicit Discrete Viscoplastic Return Residual Equation** -$$ -r_f = \Phi(f(\bm{\sigma}_{n+1}, \kappa_{n+1})) - \frac{\Delta \gamma \eta}{\Delta t} = 0 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 293_ - -**Viscoplastic Regularized Stress Solution** -$$ -\bm{\sigma}_{n+1} = \frac{\bm{\sigma}^{\mathrm{tr}} + \frac{\Delta t}{\tau} \bm{\sigma}_{\infty}}{1 + \frac{\Delta t}{\tau}}, \quad \tau = \frac{\eta}{E + K} -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 1.7, p. 68_ - -**Notation:** -\dot{\bm{\varepsilon}}^{vp}: viscoplastic strain rate tensor; f: yield function; \Phi(f): scalar overstress function; \eta: fluid viscosity parameter; \langle \cdot \rangle: Macaulay bracket operator; \bm{\sigma}: Cauchy stress tensor; \bm{\sigma}^{\mathrm{tr}}: elastic trial stress; \bm{\sigma}_{\infty}: rate-independent yield stress; \Delta \gamma: discrete plastic consistency parameter; \Delta t: time step size; \tau: characteristic relaxation time. - - -## 3. Algorithmic Implementation - -**Perzyna Viscoplasticity Implicit Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: stress } \bm{\sigma}_n, \text{ viscoplastic strain } \bm{\varepsilon}^{vp}_n, \text{ hardening variable } \kappa_n, \text{ time step } \Delta t, \text{ and viscosity } \eta$ -\State $\bm{\sigma}^{\mathrm{tr}} = \bm{\sigma}_n + \mathbf{D}^e : \Delta \bm{\varepsilon}, \quad f^{\mathrm{tr}} = f(\bm{\sigma}^{\mathrm{tr}}, \kappa_n)$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}}, \quad \bm{\varepsilon}^{vp}_{n+1} = \bm{\varepsilon}^{vp}_n, \quad \kappa_{n+1} = \kappa_n$ -\Return $\text{Step is elastic; accept trial state}$ -\Else -\EndIf -\State $\bm{\varepsilon}^{vp}_{n+1} = \bm{\varepsilon}^{vp}_n + \Delta \gamma \frac{\partial f}{\partial \bm{\sigma}_{n+1}}, \quad \kappa_{n+1} = \kappa_n + \Delta \gamma$ -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}} - \Delta \gamma \mathbf{D}^e : \frac{\partial f}{\partial \bm{\sigma}_{n+1}}$ -\Return $\text{Return updated stress } \bm{\sigma}_{n+1}, \text{ viscoplastic strain } \bm{\varepsilon}^{vp}_{n+1}, \text{ and hardening variable } \kappa_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Simo_Hughes_1998_Computational inelasticity.pdf Box 1.7, p. 68, p. 150; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 293_ - - -## 4. Known Pitfalls - -- **Assuming Zero Yield Function Excess Under Dynamic Viscoplastic Loading**: Applying rate-independent Karush-Kuhn-Tucker consistency conditions (f = 0) to Perzyna viscoplasticity prevents the stress state from exceeding the yield surface (f > 0), failing to model rate-dependent overstress behavior. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 293; Simo_Hughes_1998_Computational inelasticity.pdf p. 109)_ -- **Ill-Conditioned Explicit Integration for Small Viscosity Values**: Integrating Perzyna rate equations explicitly using forward Euler schemes when fluid viscosity parameter \eta is very small causes numerical stiffness and severe time-step restrictions (\Delta t < \tau); implicit backward Euler integration is required for stability. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 68, 150; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 293)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf -- Zabaras and Arif - 1992 - A family of integration algorithms for constitutive equations in finite deformation elasto‐viscoplas.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-radial-return.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-radial-return.md deleted file mode 100644 index 3be72a7..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-radial-return.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -id: plasticity-radial-return -title: Radial Return for J2 Plasticity -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- radial-return -- j2 -- return-mapping -- implicit -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-von-mises - type: requires - weight: 1.0 -- to: constit-stress-update-architecture - type: requires - weight: 1.0 -- to: plasticity-isotropic-hardening - type: requires - weight: 0.9 -- to: plasticity-kinematic-hardening - type: feeds-into - weight: 0.7 -- to: plasticity-consistent-tangent-j2 - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Radial Return for J2 Plasticity - -## Summary - -The radial return algorithm is an implicit backward Euler integration scheme for J2 von Mises plasticity that projects trial elastic stress radially onto the yield surface in deviatoric stress space. - -## 1. Core Concept - -The radial return algorithm integrates rate-independent J2 von Mises plastic constitutive equations over discrete finite time increments using an operator split into an elastic predictor and a plastic corrector. Under isotropic elastic response, the yield surface normal in deviatoric stress space is collinear with the trial deviatoric stress tensor \bm{s}^{\mathrm{tr}}. As established by Wilkins (1964), Simo and Hughes (1998), and Čermák et al. (2019), the plastic correction reduces to a scalar return mapping along the radial direction \bm{n}^{\mathrm{tr}} = \bm{s}^{\mathrm{tr}} / \|\bm{s}^{\mathrm{tr}}\|. For linear isotropic and kinematic hardening, the radial return projection yields a closed-form update for the discrete plastic consistency multiplier \Delta \gamma without requiring iterative local equation solving. - -## 2. Mathematical Formulation - -**Deviatoric Elastic Trial Stress and Shifted Stress** -$$ -\bm{s}^{\mathrm{tr}} = \bm{s}_n + 2G \operatorname{dev}(\Delta \bm{\varepsilon}), \quad \bm{\xi}^{\mathrm{tr}} = \bm{s}^{\mathrm{tr}} - \bm{\alpha}_n -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 120, 124; Kim_FEA for Elastoplastic Problems.pdf p. 202, 222; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598_ - -**J2 Yield Criterion Admissibility Test** -$$ -f^{\mathrm{tr}} = \|\bm{\xi}^{\mathrm{tr}}\| - \sqrt{\frac{2}{3}} \sigma_y(\bar{\varepsilon}^p_n) -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 120, 124; Kim_FEA for Elastoplastic Problems.pdf p. 202, 222_ - -**Closed-Form Plastic Multiplier Formula (Linear Hardening)** -$$ -\Delta \gamma = \frac{f^{\mathrm{tr}}}{2G + \frac{2}{3}(K^{\prime} + H^{\prime})} = \frac{\|\bm{s}^{\mathrm{tr}}\| - Y}{2G + a} -$$ -_Source: Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598; Simo_Hughes_1998_Computational inelasticity.pdf p. 124; Kim_FEA for Elastoplastic Problems.pdf p. 203, 222_ - -**Radial Return Stress and Internal State Updates** -$$ -\bm{s}_{n+1} = \bm{s}^{\mathrm{tr}} - 2G \Delta \gamma \bm{n}^{\mathrm{tr}}, \quad \bm{\alpha}_{n+1} = \bm{\alpha}_n + \frac{2}{3} H^{\prime} \Delta \gamma \bm{n}^{\mathrm{tr}}, \quad \bar{\varepsilon}^p_{n+1} = \bar{\varepsilon}^p_n + \sqrt{\frac{2}{3}} \Delta \gamma -$$ -_Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 120, 124; Kim_FEA for Elastoplastic Problems.pdf p. 202-204, 222; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598_ - -**Notation:** -\bm{s}: deviatoric Cauchy stress tensor; \bm{s}^{\mathrm{tr}}: trial elastic deviatoric stress tensor; \bm{\alpha}: back stress tensor; \bm{\xi}^{\mathrm{tr}}: trial shifted stress tensor (\bm{s}^{\mathrm{tr}} - \bm{\alpha}_n); G, \mu: elastic shear modulus; \mathbf{I}_{\mathrm{dev}}: fourth-order deviatoric projection tensor; \Delta \gamma: discrete plastic multiplier; \bm{n}^{\mathrm{tr}}: unit normal vector to yield surface (\bm{\xi}^{\mathrm{tr}} / \|\bm{\xi}^{\mathrm{tr}}\|); \sigma_y, Y: flow yield stress radius; K^{\prime}, H^{\prime}, a: plastic hardening moduli parameters. - - -## 3. Algorithmic Implementation - -**J2 Plasticity Radial Return Mapping Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: Cauchy stress } \bm{\sigma}_n, \text{ back stress } \bm{\alpha}_n, \text{ plastic strain } \bar{\varepsilon}^p_n, \text{ strain increment } \Delta \bm{\varepsilon}, \text{ shear modulus } G, \text{ bulk modulus } K, \text{ and yield stress } Y$ -\State $\bm{s}_n = \bm{\sigma}_n - \frac{1}{3} \mathrm{tr}(\bm{\sigma}_n) \mathbf{I}, \quad \bm{s}^{\mathrm{tr}} = \bm{s}_n + 2G \operatorname{dev}(\Delta \bm{\varepsilon}), \quad \bm{\xi}^{\mathrm{tr}} = \bm{s}^{\mathrm{tr}} - \bm{\alpha}_n$ -\State $f^{\mathrm{tr}} = \|\bm{\xi}^{\mathrm{tr}}\| - Y, \quad \bm{n}^{\mathrm{tr}} = \frac{\bm{\xi}^{\mathrm{tr}}}{\|\bm{\xi}^{\mathrm{tr}}\|}$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{s}^{\mathrm{tr}} + \left[ \frac{1}{3} \mathrm{tr}(\bm{\sigma}_n) + K \mathrm{tr}(\Delta \bm{\varepsilon}) \right] \mathbf{I}, \quad \bm{\alpha}_{n+1} = \bm{\alpha}_n, \quad \bar{\varepsilon}^p_{n+1} = \bar{\varepsilon}^p_n$ -\Return $\text{Step is elastic; return trial elastic state}$ -\Else -\EndIf -\State $\bm{s}_{n+1} = \bm{s}^{\mathrm{tr}} - 2G \Delta \gamma \bm{n}^{\mathrm{tr}}, \quad \bm{\alpha}_{n+1} = \bm{\alpha}_n + \frac{2}{3} H^{\prime} \Delta \gamma \bm{n}^{\mathrm{tr}}, \quad \bar{\varepsilon}^p_{n+1} = \bar{\varepsilon}^p_n + \sqrt{\frac{2}{3}} \Delta \gamma$ -\State $\bm{\sigma}_{n+1} = \bm{s}_{n+1} + \left[ \frac{1}{3} \mathrm{tr}(\bm{\sigma}_n) + K \mathrm{tr}(\Delta \bm{\varepsilon}) \right] \mathbf{I}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ back stress } \bm{\alpha}_{n+1}, \text{ and plastic strain } \bar{\varepsilon}^p_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598; Simo_Hughes_1998_Computational inelasticity.pdf p. 120-125; Kim_FEA for Elastoplastic Problems.pdf p. 202-205, 222-224_ - - -## 4. Known Pitfalls - -- **Division by Zero at Zero Trial Deviatoric Stress Norm**: Evaluating unit normal vector \bm{n}^{\mathrm{tr}} = \bm{\xi}^{\mathrm{tr}} / \|\bm{\xi}^{\mathrm{tr}}\| when the trial shifted stress vanishes (\|\bm{\xi}^{\mathrm{tr}}\| \to 0) causes floating-point division by zero; trial yield function check (f^{\mathrm{tr}} \le 0) must bypass normal evaluation. _(Source: Kim_FEA for Elastoplastic Problems.pdf p. 202-204; Zhang_1995_Explicit consistent tangent moduli with a return mapping algorithm for.pdf p. 34-35; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 598)_ -- **Inappropriately Applying Radial Return to Plane Stress Formulations**: Applying standard 3D radial return return-mapping directly to plane stress J2 plasticity violates the zero out-of-plane normal stress condition (\sigma_{33} = 0), requiring specialized constrained plane-stress return algorithms. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 125-128; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 248-250)_ -- **Using Continuum Tangent Moduli Instead of Algorithmic Consistent Tangents**: Substituting continuum elastoplastic tangent moduli for algorithmic consistent tangents in implicit global Newton-Raphson solvers destroys asymptotic quadratic convergence, leading to excessive global iteration counts. _(Source: Simo_Hughes_1998_Computational inelasticity.pdf p. 122; Kim_FEA for Elastoplastic Problems.pdf p. 205-207; Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf p. 600)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Čermák et al_2019_Efficient and flexible MATLAB implementation of 2D and 3D elastoplastic problems.pdf -- Kim_FEA for Elastoplastic Problems.pdf -- Simo_Hughes_1998_Computational inelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-von-mises.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-von-mises.md deleted file mode 100644 index f83ee0b..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-von-mises.md +++ /dev/null @@ -1,265 +0,0 @@ ---- -id: plasticity-von-mises -title: Von Mises (J2) Yield Criterion -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- yield-criterion -- j2 -- associated-flow -- von-mises -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: tensor-invariants - type: requires - weight: 1.0 - note: $f=\sqrt{3J_2}-\sigma_Y$ is built directly from the second deviatoric invariant -- to: constit-thermodynamic-framework - type: requires - weight: 0.9 - note: Associated J2 flow follows from convexity of $f$ and maximum dissipation -- to: constit-stress-update-architecture - type: requires - weight: 1.0 - note: Operator-split radial-return method specialised for J2 -- to: plasticity-general-return-mapping - type: feeds-into - weight: 1.0 - note: Closed-form J2 radial return is the canonical example -- to: plasticity-consistent-tangent-j2 - type: feeds-into - weight: 1.0 - note: J2 algorithmic tangent has a known closed form -context_size: medium -reading_priority: full -load_with: -- tensor-invariants -- plasticity-general-return-mapping -content_ref: null -akms_schema: v2 ---- - -# Von Mises (J2) Yield Criterion - -## Summary -The von Mises (J2) yield criterion $f(\boldsymbol{\sigma},\bar\varepsilon^p)=\sqrt{3J_2}-\sigma_Y(\bar\varepsilon^p)=0$ characterises pressure-independent yielding of metals: the yield surface is a circular cylinder in principal-stress space whose axis is the hydrostatic line $\sigma_1=\sigma_2=\sigma_3$. Yielding depends only on the deviatoric invariant $J_2=\tfrac12 s_{ij}s_{ij}$, expressed via the equivalent stress $\sigma_{eq}=\sqrt{3J_2}$. Associated flow $\dot{\boldsymbol{\varepsilon}}^p=\dot\gamma\,\partial f/\partial\boldsymbol{\sigma}=\dot\gamma\,\sqrt{\tfrac32}\,\mathbf{s}/\|\mathbf{s}\|$ delivers normality (flow direction along outward normal of the cylinder), automatically guarantees positive dissipation, and enforces plastic incompressibility $\mathrm{tr}\,\dot{\boldsymbol{\varepsilon}}^p=0$. Consistency $f=0,\,\dot f=0$ during plastic loading combined with the flow rule and isotropic hardening $\sigma_Y=\sigma_Y(\bar\varepsilon^p)$ produces a closed-form radial-return algorithm: $\Delta\gamma$ solves $\sqrt{3J_2^{\mathrm{trial}}}-3\mu\Delta\gamma-\sigma_Y(\bar\varepsilon^p_n+\Delta\gamma)=0$, then $\boldsymbol{\sigma}_{n+1}=\boldsymbol{\sigma}^{\mathrm{trial}}-2\mu\Delta\gamma\sqrt{\tfrac32}\mathbf{s}^{\mathrm{trial}}/\|\mathbf{s}^{\mathrm{trial}}\|$. - - -## 1. Core Concept -J2 plasticity is the simplest realistic plasticity model and the foundation of nearly every metals-plasticity computation. Two physical observations underpin it: (1) hydrostatic stress does NOT cause yielding in metals — submerging a metal block in fluid produces no permanent deformation no matter how large the pressure; (2) yielding is fundamentally a shear / distortion process driven by dislocation glide on slip planes, captured by the deviator. The yield function $f=\sqrt{3J_2}-\sigma_Y$ encodes both: it is built from $J_2$ alone (hydrostatic-independent) and reaches yield when the equivalent shear stress $\sqrt{3J_2}$ — the Mises equivalent stress, equal to $\sigma$ in uniaxial tension — exceeds the yield strength $\sigma_Y$. Associated flow follows from convexity of $f$ via the maximum dissipation principle: the flow direction is the outward normal to the yield surface, which for $f=\sqrt{3J_2}-\sigma_Y$ is $\sqrt{3/2}\,\mathbf{s}/\|\mathbf{s}\|$ — purely deviatoric, giving plastic incompressibility for free. The combination of (a) closed-form yield function, (b) closed-form flow rule, (c) closed-form radial-return solution makes J2 the testbed for stress-update architectures and the gold-standard benchmark before extending to GTN, Hill, Drucker-Prager. The factor-of-$\sqrt{3}$ vs $\sqrt{2}$ debate in different references is the most common source of bugs. - - -## 2. Mathematical Formulation -Throughout, $\boldsymbol{\sigma}$ Cauchy stress, $\mathbf{s}=\mathrm{dev}\,\boldsymbol{\sigma}=\boldsymbol{\sigma}-\tfrac13\,\mathrm{tr}\boldsymbol{\sigma}\,\mathbf{I}$ deviator, $J_2=\tfrac12\,\mathbf{s}\colon\mathbf{s}=\tfrac12 s_{ij}s_{ij}$, $\sigma_{eq}=\sqrt{3J_2}$ Mises equivalent stress. $\bar\varepsilon^p$ accumulated equivalent plastic strain, $H=d\sigma_Y/d\bar\varepsilon^p$ isotropic hardening modulus. $\mu$ shear modulus, $\kappa$ bulk modulus. - - -**von Mises yield function:** - -$$ -f(\boldsymbol{\sigma}, \bar\varepsilon^p) = \sqrt{3 J_2} - \sigma_Y(\bar\varepsilon^p) = \sigma_{eq} - \sigma_Y -$$ - -where Equivalent forms; $\sigma_{eq}=\sqrt{3J_2}$ - -**Equivalent stress and equivalent plastic strain:** - -$$ -\sigma_{eq} = \sqrt{\tfrac{3}{2}\,\mathbf{s}\colon\mathbf{s}} = \sqrt{3 J_2},\qquad -\bar\varepsilon^p = \int_0^t \sqrt{\tfrac{2}{3}\,\dot{\boldsymbol{\varepsilon}}^p\colon\dot{\boldsymbol{\varepsilon}}^p}\,d\tau -$$ - -where Both reduce to $\sigma_{11}$ and $\varepsilon^p_{11}$ in uniaxial tension; the factors $\sqrt{3/2},\sqrt{2/3}$ ensure consistency with uniaxial yield strength - -**Flow direction (associated flow):** - -$$ -\mathbf{N} = \frac{\partial f}{\partial \boldsymbol{\sigma}} - = \sqrt{\tfrac{3}{2}}\,\frac{\mathbf{s}}{\|\mathbf{s}\|} - = \frac{3}{2\,\sigma_{eq}}\,\mathbf{s} -$$ - -where $\|\mathbf{s}\|=\sqrt{\mathbf{s}\colon\mathbf{s}}=\sqrt{2J_2}$; equivalent forms - -**Plastic flow rule:** - -$$ -\dot{\boldsymbol{\varepsilon}}^p = \dot\gamma\,\mathbf{N},\qquad -\dot{\bar\varepsilon}^p = \dot\gamma -$$ - -where Flow direction $\mathbf{N}$ deviatoric $\Rightarrow$ $\mathrm{tr}\,\dot{\boldsymbol{\varepsilon}}^p=0$ (plastic incompressibility) - -**Karush-Kuhn-Tucker conditions:** - -$$ -\dot\gamma\ge 0,\qquad f\le 0,\qquad \dot\gamma\,f = 0 -$$ - -where Either elastic ($\dot\gamma=0$, $f<0$) or plastic ($\dot\gamma>0$, $f=0$) - -**Consistency during plastic loading:** - -$$ -\dot f = \mathbf{N}\colon\dot{\boldsymbol{\sigma}} - H\,\dot\gamma = 0 -$$ - -where $H=d\sigma_Y/d\bar\varepsilon^p$ isotropic hardening modulus; gives the consistency condition for $\dot\gamma$ - -**Closed-form radial return for J2:** - -$$ -\Delta\gamma\,\text{solves}\,\sqrt{3 J_2^{\mathrm{trial}}} - 3\mu\,\Delta\gamma - \sigma_Y(\bar\varepsilon^p_n+\Delta\gamma) = 0,\qquad -\mathbf{s}_{n+1} = \frac{\sigma_Y(\bar\varepsilon^p_{n+1})}{\sqrt{3 J_2^{\mathrm{trial}}}}\,\mathbf{s}^{\mathrm{trial}} -$$ - -where Single scalar nonlinear equation in $\Delta\gamma$; linear hardening gives closed form $\Delta\gamma=(\sqrt{3J_2^{\mathrm{trial}}}-\sigma_Y(\bar\varepsilon^p_n))/(3\mu+H)$ - -**Algorithmic consistent tangent (J2):** - -$$ -\mathbb{C}^{\mathrm{alg}}_{ijkl} -= \kappa\,\delta_{ij}\delta_{kl} -+ 2\mu\,\theta\,\!\left(\mathbb{I}^{\mathrm{sym}}_{ijkl} - \tfrac{1}{3}\delta_{ij}\delta_{kl}\right) -- 2\mu\,\bar\theta\,\hat n_{ij}\hat n_{kl} -$$ - -where $\theta=1-2\mu\Delta\gamma/\|\mathbf{s}^{\mathrm{trial}}\|$, $\bar\theta=1/(1+H/(3\mu))-(1-\theta)$, $\hat{\mathbf{n}}=\mathbf{s}^{\mathrm{trial}}/\|\mathbf{s}^{\mathrm{trial}}\|$ - -**Plastic incompressibility:** - -$$ -\mathrm{tr}\,\dot{\boldsymbol{\varepsilon}}^p = 0\;\Rightarrow\; -\det\,\mathbf{F}^p = 1\,\text{(finite strain)},\;\; -\mathrm{tr}\,\boldsymbol{\varepsilon}^p_n = 0\,\text{(small strain)} -$$ - -where Automatic consequence of associated J2 flow - -**Continuum tangent (NOT for use in implicit Newton):** - -$$ -\mathbb{C}^{ep}_{ijkl} = \mathbb{C}^e_{ijkl} -- \frac{(\mathbb{C}^e\colon\mathbf{N})_{ij}\,(\mathbf{N}\colon\mathbb{C}^e)_{kl}}{\mathbf{N}\colon\mathbb{C}^e\colon\mathbf{N} + H} -$$ - -where Mistakenly equating $\mathbb{C}^{ep}$ with $\mathbb{C}^{\mathrm{alg}}$ is the most common Newton-convergence pitfall - -**Notation:** - -- $J_2$ — Second deviatoric invariant, $\tfrac12\mathbf{s}\colon\mathbf{s}$ -- $\sigma_{eq}$ — von Mises equivalent stress, $\sqrt{3J_2}$ -- $\mathbf{s}$ — Stress deviator -- $\sigma_Y(\bar\varepsilon^p)$ — Yield strength as function of accumulated plastic strain -- $\bar\varepsilon^p$ — Equivalent plastic strain -- $H$ — Isotropic hardening modulus, $H=d\sigma_Y/d\bar\varepsilon^p$ -- $\mathbf{N}$ — Flow direction $\partial f/\partial \boldsymbol{\sigma}$ -- $\dot\gamma,\Delta\gamma$ — Plastic multiplier (rate / increment) -- $\mathbb{C}^{\mathrm{alg}}$ — Algorithmically consistent tangent -- $\theta,\bar\theta$ — Coefficients in the algorithmic tangent (Souza Neto et al.) -- $\hat{\mathbf{n}}$ — Unit deviator direction $\mathbf{s}^{\mathrm{trial}}/\|\mathbf{s}^{\mathrm{trial}}\|$ - - -## 3. Algorithmic Implementation -**Algorithm: Closed-Form Small-Strain J2 Radial Return (Linear Hardening)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{s}^{\mathrm{trial}},\,p^{\mathrm{trial}},\,\bar\varepsilon^p_n,\,\mu,\kappa,\,\sigma_Y(\bar\varepsilon^p)=\sigma_{Y0}+H\bar\varepsilon^p$ -\State $\sqrt{3J_2^{\mathrm{trial}}} \gets \sqrt{\tfrac{3}{2}\,\mathbf{s}^{\mathrm{trial}}\colon\mathbf{s}^{\mathrm{trial}}}$ -\State $f^{\mathrm{trial}} \gets \sqrt{3J_2^{\mathrm{trial}}} - (\sigma_{Y0} + H\,\bar\varepsilon^p_n)$ -\If{$f^{\mathrm{trial}} \le 0$} -\State $\Delta\gamma \gets 0,\,\boldsymbol{\sigma}_{n+1} \gets \mathbf{s}^{\mathrm{trial}} - p^{\mathrm{trial}}\mathbf{I}$ -\Return $\boldsymbol{\sigma}_{n+1},\bar\varepsilon^p_n,\mathbb{C}^{\mathrm{alg}}=\mathbb{C}^e$ -\EndIf -\State $\Delta\gamma \gets f^{\mathrm{trial}} / (3\mu + H) \;\text{(closed-form for linear hardening)}$ -\State $\hat{\mathbf{n}} \gets \mathbf{s}^{\mathrm{trial}} / \|\mathbf{s}^{\mathrm{trial}}\|$ -\State $\mathbf{s}_{n+1} \gets \mathbf{s}^{\mathrm{trial}} - 2\mu\,\Delta\gamma\,\sqrt{\tfrac{3}{2}}\,\hat{\mathbf{n}}$ -\State $\boldsymbol{\sigma}_{n+1} \gets -p^{\mathrm{trial}}\,\mathbf{I} + \mathbf{s}_{n+1}$ -\State $\bar\varepsilon^p_{n+1} \gets \bar\varepsilon^p_n + \Delta\gamma$ -\State $\boldsymbol{\varepsilon}^p_{n+1} \gets \boldsymbol{\varepsilon}^p_n + \Delta\gamma\,\sqrt{\tfrac{3}{2}}\,\hat{\mathbf{n}}$ -\Return $\boldsymbol{\sigma}_{n+1},\bar\varepsilon^p_{n+1},\boldsymbol{\varepsilon}^p_{n+1},\mathbb{C}^{\mathrm{alg}}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Closed form for linear hardening: NO local Newton needed. Per-Gauss-point cost: ~30 FMAs + 1 sqrt + 1 division. For nonlinear hardening ($\sigma_Y(\bar\varepsilon^p)$ tabulated / power-law / Voce) replace the closed-form $\Delta\gamma$ by a 1D Newton on $g(\Delta\gamma)=\sqrt{3J_2^{\mathrm{trial}}}-3\mu\Delta\gamma-\sigma_Y(\bar\varepsilon^p_n+\Delta\gamma)=0$ — typically 3-5 iterations to $\tau=10^{-10}\sigma_Y$. Cache $\hat{\mathbf{n}}$ since it equals the post-update flow direction (radial return). - - -**Algorithm: J2 Algorithmic Consistent Tangent** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{s}^{\mathrm{trial}},\Delta\gamma,\mu,\kappa,H$ -\State $\hat{\mathbf{n}} \gets \mathbf{s}^{\mathrm{trial}}/\|\mathbf{s}^{\mathrm{trial}}\|$ -\State $\theta \gets 1 - 2\mu\Delta\gamma/\|\mathbf{s}^{\mathrm{trial}}\|$ -\State $\bar\theta \gets 1/(1+H/(3\mu)) - (1-\theta)$ -\For{$i,j,k,l = 1,2,3$} -\State $\mathbb{C}^{\mathrm{alg}}_{ijkl} \gets \kappa\,\delta_{ij}\delta_{kl} + 2\mu\,\theta\,(\mathbb{I}^{\mathrm{sym}}_{ijkl}-\tfrac{1}{3}\delta_{ij}\delta_{kl}) - 2\mu\,\bar\theta\,\hat n_{ij}\hat n_{kl}$ -\EndFor -\Return $\mathbb{C}^{\mathrm{alg}}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Three contributions: bulk ($\kappa\,\mathbf{I}\otimes\mathbf{I}$), shear-symmetric ($2\mu\theta\,\mathbb{I}^{\mathrm{sym},\mathrm{dev}}$), correction ($-2\mu\bar\theta\,\hat{\mathbf{n}}\otimes\hat{\mathbf{n}}$). Store directly in Mandel form ($6\times 6$); the structure is symmetric major / minor by construction. The factor $\theta<1$ on the deviatoric block reflects shear softening due to plastic flow; $\bar\theta$ encodes the projection onto the flow direction. - - -**Algorithm: Nonlinear Hardening Local Newton** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \sqrt{3J_2^{\mathrm{trial}}},\bar\varepsilon^p_n,\mu,\sigma_Y(\bar\varepsilon^p)\,\text{(possibly nonlinear)}$ -\State $\Delta\gamma^0 \gets f^{\mathrm{trial}}/(3\mu+H_0) \;\text{(linear-hardening initial guess)}$ -\For{$k = 0,1,\ldots,K-1$} -\State $\bar\varepsilon^p \gets \bar\varepsilon^p_n + \Delta\gamma^k$ -\State $g \gets \sqrt{3J_2^{\mathrm{trial}}} - 3\mu\Delta\gamma^k - \sigma_Y(\bar\varepsilon^p)$ -\State $g' \gets -3\mu - H(\bar\varepsilon^p)$ -\State $\Delta\gamma^{k+1} \gets \Delta\gamma^k - g/g'$ -\If{$|g| < \tau\,\sigma_{Y0}$} -\State $\textbf{break}$ -\EndIf -\EndFor -\Return $\Delta\gamma$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -1D Newton on $\Delta\gamma$ — converges in 3-5 iterations to $\tau=10^{-10}\sigma_{Y0}$. The derivative $g'(\Delta\gamma)=-3\mu-H(\bar\varepsilon^p)$ involves the local hardening modulus $H$ at the current $\bar\varepsilon^p$. For tabulated $\sigma_Y$ use linear interpolation between tabulated points (and constant-$H$ within each interval); for power-law $\sigma_Y=\sigma_{Y0}+K(\bar\varepsilon^p)^n$, $H=Kn(\bar\varepsilon^p)^{n-1}$. - - - -## 4. Known Pitfalls -**Confusion between $\sqrt{3J_2}$ and $\sqrt{2J_2}$:** Different conventions exist: Mises equivalent stress $\sigma_{eq}=\sqrt{3J_2}$ (matches uniaxial $\sigma_{11}$) vs effective shear stress $\tau_{eq}=\sqrt{J_2}$ (Tresca / max-shear convention). The factor $\sqrt{3}$ vs $\sqrt{2}$ determines whether yield strength is reported in tension or shear. Document the convention and verify on a uniaxial test ($\sigma_{eq}$ should equal $\sigma_{11}$) and a pure-shear test ($\sigma_{eq}=\sqrt{3}\tau$). - - -**Wrong factor in flow rule normalisation:** Associated flow gives $\mathbf{N}=\sqrt{3/2}\,\mathbf{s}/\|\mathbf{s}\|$, not $\mathbf{s}/\|\mathbf{s}\|$ (which would be the unit deviator direction without the $\sqrt{3/2}$ factor). Forgetting the factor halves the plastic strain rate; the simulation appears to "harden too quickly" because $\bar\varepsilon^p$ accumulates more slowly than expected. - - -**Plastic incompressibility drift under explicit integration:** Forward-Euler $\boldsymbol{\varepsilon}^p_{n+1}=\boldsymbol{\varepsilon}^p_n+\Delta t\,\dot\gamma\mathbf{N}_n$ accumulates round-off in $\mathrm{tr}\,\boldsymbol{\varepsilon}^p$ that drifts away from zero. Detect $|\mathrm{tr}\,\boldsymbol{\varepsilon}^p|>10^{-10}$ and project back to deviatoric. Implicit (radial return) is exact in plastic incompressibility because $\mathbf{N}$ is recomputed from the deviator at $n+1$. - - -**Applying J2 to pressure-sensitive materials:** J2 is correct for non-porous metals but wrong for soils, concrete, foams, geomaterials where yielding depends on hydrostatic pressure (friction angle, dilatancy). Use Drucker-Prager or Mohr-Coulomb (`plasticity-drucker-prager`) or porous-plasticity GTN for those. Mistakenly using J2 on rock predicts no shear band and no failure under triaxial compression. - - -**Wrong sign on consistent-tangent denominator:** Continuum tangent $\mathbb{C}^{ep}=\mathbb{C}^e-(\mathbb{C}^e\colon\mathbf{N})\otimes(\mathbf{N}\colon\mathbb{C}^e)/(\mathbf{N}\colon\mathbb{C}^e\colon\mathbf{N}+H)$. For softening ($H<0$) the denominator can vanish (localisation onset) — the tangent diverges. For purely-plastic ($H=0$) it is finite. Check the denominator sign before dividing; near-zero indicates onset of localisation / instability. - - -**Continuum vs algorithmic tangent:** The continuum tangent $\mathbb{C}^{ep}$ above relates infinitesimal stress / strain rates; the algorithmic tangent $\mathbb{C}^{\mathrm{alg}}$ (with $\theta,\bar\theta$ corrections) relates FINITE step increments. They differ by the implicit dependence of $\Delta\gamma$ on $\Delta\boldsymbol{\varepsilon}$. Using $\mathbb{C}^{ep}$ in implicit Newton degrades convergence to linear; always use $\mathbb{C}^{\mathrm{alg}}$. - - -**Negative $\Delta\gamma$ from poor initial guess:** Local Newton on $\Delta\gamma$ can briefly produce $\Delta\gamma^k<0$ if the initial guess overshoots. Project to $\Delta\gamma^{k+1}=\max(\Delta\gamma^{k+1}, 0)$ — KKT requires $\Delta\gamma\ge 0$. Without the projection the algorithm can converge to a non-physical negative root. - - -**Hardening evaluation at wrong state:** $\sigma_Y(\bar\varepsilon^p_{n+1})$ MUST use the END-of-step plastic strain $\bar\varepsilon^p_{n+1}=\bar\varepsilon^p_n+\Delta\gamma$, NOT $\bar\varepsilon^p_n$. A common bug uses $\sigma_Y(\bar\varepsilon^p_n)$ in the residual $g$, which produces explicit Euler hardening instead of implicit. The residual then misses the hardening contribution and the simulation predicts wrong yield evolution. - - -## 5. References -- von Mises (1913) — Mechanik der festen Korper im plastisch deformablen Zustand (original formulation of $J_2$ yield criterion) -- Simo & Hughes (1998) — Computational Inelasticity, Ch. 2 (radial return, algorithmic consistent tangent for J2) -- Souza Neto, Peric, Owen (2008) — Computational Methods for Plasticity (closed-form J2 algorithmic tangent with $\theta, \bar\theta$) -- Dunne & Petrinic (2005) — Introduction to Computational Plasticity, Ch. 5 (radial return method, Figs 5.1a/b explicit vs implicit) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/plasticity-zerilli-armstrong.md b/packages/akms/src/akms/_bundled/global_nodes/plasticity-zerilli-armstrong.md deleted file mode 100644 index 4ba9256..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/plasticity-zerilli-armstrong.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: plasticity-zerilli-armstrong -title: Zerilli-Armstrong Model -domain: computational-mechanics -subdomain: plasticity -tags: -- plasticity -- zerilli-armstrong -- dislocation-mechanics -- rate-dependent -- bcc-fcc -status: established -confidence: 0.9 -source: hybrid -edges: -- to: plasticity-johnson-cook - type: contradicts - weight: 0.6 -- to: plasticity-isotropic-hardening - type: refines - weight: 0.6 -- to: plasticity-von-mises - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Zerilli-Armstrong Model - -## Summary - -Rate-dependent constitutive formulations model flow stress as a function of plastic strain, strain rate, and temperature in dynamic inelasticity. - -## 1. Core Concept - -In dynamic impact and high-strain-rate metal plasticity, flow stress exhibits strong sensitivity to strain rate and thermal softening. Rate-dependent constitutive models represent flow stress Y(\bar{\varepsilon}, \dot{\bar{\varepsilon}}, T) as a function of equivalent plastic strain \bar{\varepsilon}, plastic strain rate \dot{\bar{\varepsilon}}, and temperature T. Integrated within finite-strain multiplicative elastoplasticity (\mathbf{F} = \mathbf{F}^e \mathbf{F}^p) or inelastic equation of state (IEOS) frameworks, rate-dependent flow stress laws govern plastic dissipation, dynamic return mapping, and thermal softening under high-velocity loading. - -## 2. Mathematical Formulation - -**Rate-Dependent Flow Stress Functional Form** -$$ -Y(\bar{\varepsilon}, \dot{\bar{\varepsilon}}, T) = Y_0(\bar{\varepsilon}) \cdot g_r(\dot{\bar{\varepsilon}}) \cdot g_t(T) -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 198_ - -**Finite-Strain Rate-Dependent Yield Condition** -$$ -F(\bm{\tau}, \bar{\varepsilon}, T) = \bar{\tau} - Y(\bar{\varepsilon}, \dot{\bar{\varepsilon}}, T) = 0 -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 278, 281_ - -**Rate-Dependent Plastic Multiplier Evolution** -$$ -\dot{\bar{\varepsilon}} = \dot{\lambda}, \quad \dot{\mathbf{F}}^p = \dot{\lambda} \mathbf{R}_e^T \cdot \frac{\partial F}{\partial \bm{\tau}} \cdot \mathbf{R}_e \cdot \mathbf{F}^p -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 276, 278_ - -**Notation:** -Y: rate-dependent flow stress; Y_0: static strain-hardening stress; g_r: strain rate sensitivity function; g_t: thermal softening function; \bar{\varepsilon}: equivalent plastic strain; \dot{\bar{\varepsilon}}: equivalent plastic strain rate; T: absolute temperature; \bm{\tau}: Kirchhoff stress tensor; \bar{\tau}: equivalent von Mises Kirchhoff stress; F: yield function; \mathbf{F}^p: plastic deformation gradient tensor; \mathbf{R}_e: elastic rotation tensor; \dot{\lambda}: plastic consistency parameter rate. - - -## 3. Algorithmic Implementation - -**Rate-Dependent Flow Stress Return-Mapping Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: elastic strain } \bm{\varepsilon}^e_n, \text{ plastic strain } \bar{\varepsilon}_n, \text{ temperature } T_n, \text{ and total strain increment } \Delta \bm{\varepsilon}$ -\State $\bm{\varepsilon}^{e,tr} = \bm{\varepsilon}^e_n + \Delta \bm{\varepsilon}, \quad \bm{\tau}^{tr} = \mathbf{D}^e : \bm{\varepsilon}^{e,tr}, \quad \bar{\tau}^{tr} = \sqrt{\frac{3}{2}\bm{s}^{tr}:\bm{s}^{tr}}$ -\State $Y^{tr} = Y\left(\bar{\varepsilon}_n, \frac{\Delta \bar{\varepsilon}}{\Delta t}, T_n\right), \quad F^{tr} = \bar{\tau}^{tr} - Y^{tr}$ -\If{$F^{tr} \le 0$} -\State $\bm{\sigma}_{n+1} = J^{-1} \bm{\tau}^{tr}, \quad \bar{\varepsilon}_{n+1} = \bar{\varepsilon}_n, \quad T_{n+1} = T_n$ -\Return $\text{Step is elastic; accept trial state}$ -\Else -\EndIf -\State $\bar{\varepsilon}_{n+1} = \bar{\varepsilon}_n + \Delta \lambda, \quad \bm{\varepsilon}^e_{n+1} = \bm{\varepsilon}^{e,tr} - \Delta \lambda \mathbf{N}_{n+1}, \quad \bm{\sigma}_{n+1} = J_{n+1}^{-1} \bm{\tau}_{n+1}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ plastic strain } \bar{\varepsilon}_{n+1}, \text{ and temperature } T_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 278, 283-285; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 198_ - - -## 4. Known Pitfalls - -- **Singularity at Low Strain Rates in Logarithmic Rate Formulations**: Evaluating rate-dependent flow stress models with logarithmic rate terms as plastic strain rate approaches zero (\dot{\bar{\varepsilon}} \to 0) produces minus infinity numerical singularities unless bounded by a reference rate floor. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 198)_ -- **Neglecting Thermal Softening at Elevated Temperatures**: Omitted thermal softening terms in rate-dependent flow stress functions underpredicts thermal softening during adiabatic plastic heating, causing artificial overestimation of stress levels. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277, 280; Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 8)_ -- **Thermodynamic Inconsistency in Uncoupled Pressure-Flow Stress Integration**: Evaluating hydrostatic pressure from an uncoupled EOS while applying rate-dependent flow stress models to deviatoric stress updates violates thermodynamic energy balance during thermo-mechanical return mapping. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 280, 284)_ - -## References - -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/precond-amg-gpu.md b/packages/akms/src/akms/_bundled/global_nodes/precond-amg-gpu.md deleted file mode 100644 index fa33289..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/precond-amg-gpu.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: precond-amg-gpu -title: 'AMG on GPU: Setup, Smoothers, & Coarse-Solve' -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- AMG -- GPU -- AmgX -- hypre -- parallel-smoother -status: established -confidence: 0.9 -source: hybrid -edges: -- to: precond-amg-theory - type: refines - weight: 0.7 -- to: precond-gpu-alternatives - type: requires - weight: 1.0 -- to: solver-pcg-algorithm - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# AMG on GPU: Setup, Smoothers, & Coarse-Solve - -## Summary - -Algebraic Multigrid (AMG) on Graphics Processing Units (GPUs) accelerates iterative linear solvers for large-scale finite element discretizations by executing multi-level V-cycles entirely within GPU device memory. To maximize throughput on heterogeneous GPU architectures, standard sequential Jacobi or Gauss-Seidel relaxations are replaced by fine-grained parallel polynomial (e.g., 2nd-order Chebyshev with Jacobi scaling) or block-diagonal smoothers. By combining matrix-free p-multigrid discretizations at high polynomial orders with GPU-accelerated sparse AMG coarse solvers (such as hypre BoomerAMG or AmgX) and eliminating host-device memory transfers via direct array pointers, GPU AMG achieves high parallel efficiency across millions to billions of degrees of freedom. - -## 1. Core Concept - -Algebraic Multigrid on GPUs solves large, sparse, symmetric positive-definite linear systems Ax = b arising from finite element discretizations without requiring explicit geometric grid hierarchies. On parallel GPU hardware, the AMG V-cycle performs hierarchical error elimination: high-frequency error components are damped on fine grids using parallel-friendly smoothers (such as Chebyshev-polynomial Jacobi iterations), while low-frequency error components are restricted to coarser levels using Galerkin projections A_c = P^T A_f P. In high-order finite element frameworks, AMG serves as the coarse-level solver for matrix-free p-multigrid (p-MG) hierarchies, where linear Q1 elements are assembled into CSR sparse matrices on the GPU using split-phase COO interfaces. Eliminating CPU-GPU data transfers by maintaining sparse operators, vectors, and preconditioner structures in device memory is critical, as host-device memory transfer latency can destroy GPU speedup. Furthermore, in non-linear or transient simulations, AMG setup costs (coarsening analysis and Galerkin operator construction) are amortized across multiple time steps or quasi-Newton iterations. - -## 2. Mathematical Formulation - -**galerkin-coarse-operator** -$$ -A_c = P_{c \to f}^T A_f P_{c \to f} -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Section III.A, p. 3_ - -**chebyshev-jacobi-smoother-update** -$$ -u^{(l+1)} = u^{(l)} + \hat{M}^{-1} (b - A_f u^{(l)}) -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Section III.A, p. 3_ - -**gpu-device-matrix-pointer-access** -$$ -A_{\text{device}} = \text{MatSeqAIJCUSPARSEGetArray}(A) -$$ -_Source: Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.5, p. 5_ - -**Notation:** -A_f, A_c represent fine and coarse linear system stiffness matrices; P_{c \to f} represents prolongation operator from coarse to fine level; r_f represents residual vector; u_f represents primal displacement solution vector; \hat{M}^{-1} represents Chebyshev/Jacobi smoother operator; \lambda_{\max} represents maximum eigenvalue estimate of preconditioned operator. - - -## 3. Algorithmic Implementation - -**gpu-amg-v-cycle-step** -$$ -\begin{algorithmic} -\State $\text{Initialize fine solution } u_f \text{ and residual } r_f = b - A_f u_f \text{ on GPU device}$ -\State $u_f \leftarrow u_f + \hat{M}^{-1} r_f \quad \text{(Pre-smoothing via Chebyshev/Jacobi iteration on GPU)}$ -\State $r_c = P_{c \to f}^T (b - A_f u_f) \quad \text{(Restrict residual to coarse grid via GPU SpMV)}$ -\If{$\text{Level } c \text{ is coarsest grid}$} -\State $e_c = A_c^{-1} r_c \quad \text{(Solve coarse system via GPU BoomerAMG or sparse factorization)}$ -\Else -\EndIf -\State $u_f \leftarrow u_f + P_{c \to f} e_c \quad \text{(Prolong error correction to fine grid on GPU)}$ -\State $u_f \leftarrow u_f + \hat{M}^{-1} (b - A_f u_f) \quad \text{(Post-smoothing via Chebyshev/Jacobi iteration on GPU)}$ -\Return $u_f$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Section III.A, p. 3, Fig. 2; Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 4.5, pp. 10-12_ - -**matrix-free-pmg-amg-coarse-solve** -$$ -\begin{algorithmic} -\State $\text{Execute high-order } Q_p \text{ matrix-free smoothing loops on GPU via fused quadrature kernels}$ -\State $\text{Restrict residual down to linear } Q_1 \text{ coarse element level } r_1 = P_{1 \to p}^T r_p$ -\State $\text{Assemble } Q_1 \text{ CSR matrix } A_1 \text{ on GPU using split-phase COO } \text{MatSetValuesCOO}$ -\State $\text{Solve } A_1 e_1 = r_1 \text{ using GPU BoomerAMG (hypre) or GAMG preconditioner}$ -\State $\text{Prolong error correction } e_p = P_{1 \to p} e_1 \text{ to high-order } Q_p \text{ space}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Section II.C-III.A, pp. 2-4_ - - -## 4. Known Pitfalls - -- **cpu-gpu-data-transfer-latency-penalty**: Assembling linear systems on the host CPU and copying matrices or vectors to the GPU prior to AMG preconditioning introduces massive PCI-e communication latency. Unnecessary CPU-GPU data transfers eliminate all computational performance gains of GPU acceleration. Assembly and linear solves must reside entirely in GPU device memory using direct device array pointers (e.g., MatSeqAIJCUSPARSEGetArray). _(Source: Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.5, p. 5; Section 4.5, p. 10)_ -- **amg-setup-overhead-unamortized**: Constructing algebraic multigrid hierarchies (coarsening graphs, Galerkin matrix-matrix products A_c = P^T A_f P, and eigenvalue estimation) carries high computational overhead on GPUs (often accounting for ~50% or more of total solution time per step). Re-building AMG preconditioners at every step without reusing setup across multiple quasi-Newton or transient time increments degrades overall solver efficiency. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Section V.C, pp. 8-10; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.3.1, p. 22)_ -- **gpu-memory-capacity-exhaustion-coarse-level**: High-order finite element discretizations generate dense connectivity graphs when coarsened via CSR sparse matrix assembly. For models exceeding tens of millions of degrees of freedom, allocating assembled coarse-grid CSR sparse matrices and AMG multi-level hierarchy buffers on a single GPU can exhaust GPU VRAM capacity, causing out-of-memory solver failure unless managed via matrix-free p-multigrid or multi-GPU distribution. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Section V.B, p. 6; Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 4.5, p. 12)_ - -## References - -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf -- Trotter et al_2023_Targeting performance and user-friendliness.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- IterMethBook_2ndEd.pdf.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/precond-amg-theory.md b/packages/akms/src/akms/_bundled/global_nodes/precond-amg-theory.md deleted file mode 100644 index c10457e..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/precond-amg-theory.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: precond-amg-theory -title: 'Algebraic Multigrid (AMG): Theory & Setup' -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- AMG -- multigrid -- coarsening -- interpolation -- near-null-space -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-pcg-algorithm - type: feeds-into - weight: 0.5 -- to: precond-amg-gpu - type: refines - weight: 0.7 -- to: precond-geometric-mg - type: refines - weight: 0.7 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Algebraic Multigrid (AMG): Theory & Setup - -## Summary - -Algebraic Multigrid (AMG) is a multi-level preconditioning methodology for large, sparse, symmetric positive-definite linear systems arising from finite element discretizations in computational mechanics. Unlike geometric multigrid, AMG constructs coarse-grid hierarchies, restriction/prolongation operators, and coarse system operators purely algebraically from assembled coefficient matrices without requiring access to geometric grid structures or unstructured mesh sequences. By pairing parallel smoothers (such as Chebyshev polynomials or Richardson relaxation) for high-frequency error reduction with Galerkin coarse-grid corrections for low-frequency error elimination, AMG bounds condition number growth and achieves scalable convergence. - -## 1. Core Concept - -Multigrid methods accelerate Krylov subspace iterative solvers (such as Preconditioned Conjugate Gradient) by eliminating algebraic error across a hierarchy of spatial discretization scales. High-frequency error components are rapidly damped on fine grids using local smoothing iterations (such as Jacobi, Gauss-Seidel, or 2nd-order Chebyshev polynomial smoothers), whereas low-frequency error components are restricted to coarser representations where they appear high-frequency and can be eliminated inexpensively. While geometric multigrid requires generating nested unstructured mesh hierarchies—a complex task for arbitrary 3D domains—AMG constructs coarse levels algebraically using matrix entry connectivity. Main AMG paradigms include classical AMG (Ruge and Stüben), agglomeration AMG, and smoothed aggregation AMG (Vaněk et al.). In smoothed aggregation AMG, aggregate nodal blocks are formed, and prolongation operators P are damped via local matrix smoothing to eliminate errors corresponding to small eigenvalues. The coarse operator is formed via Galerkin projection A_c = P^T A_f P. The hierarchy terminates at a coarsest level small enough to be solved directly via exact LU factorization or block Jacobi with incomplete Cholesky (IC) decomposition. - -## 2. Mathematical Formulation - -**galerkin-coarse-grid-operator** -$$ -A_c = P^T A_f P -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 9; Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3; IterMethBook_2ndEd.pdf.pdf, Section 13.4, p. 440_ - -**smoothed-aggregation-prolongation** -$$ -P = (I - \omega D^{-1} A_{\text{filtered}}) \tilde{P} -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 10_ - -**chebyshev-jacobi-smoother** -$$ -u^{(l+1)} = u^{(l)} + \hat{M}^{-1} (b - A_f u^{(l)}) -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 10_ - -**amg-condition-number-reduction** -$$ -\text{cond}_2(M_{\text{AMG}}^{-1} A) \approx \frac{\max |\lambda_i(M_{\text{AMG}}^{-1} A)|}{\min |\lambda_i(M_{\text{AMG}}^{-1} A)|} \ll \text{cond}_2(M_{\text{Jacobi}}^{-1} A) -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.2.3, pp. 16-18_ - -**Notation:** -A_f, A_c represent fine and coarse level stiffness matrices; P represents prolongation operator matrix; R = P^T represents restriction operator matrix; \tilde{P} represents tentative un-smoothed aggregation matrix; \hat{M}^{-1} represents smoothing preconditioning operator; \lambda_i represents eigenspectrum computed via Lanczos iterations; cond_2 represents spectral condition number. - - -## 3. Algorithmic Implementation - -**amg-setup-and-hierarchy-construction** -$$ -\begin{algorithmic} -\State $\text{Given fine-grid assembled matrix } A_0 = A_f \text{ and level } l = 0$ -\While{$\text{dim}(A_l) > n_{\text{coarsest}}$} -\State $\text{Construct un-smoothed aggregation blocks or C/F node partitioning from adjacency graph of } A_l$ -\State $\text{Form prolongation matrix } P_{l+1 \to l} \text{ via smoothed aggregation } P = (I - \omega D^{-1} A_{\text{filt}}) \tilde{P}$ -\State $\text{Build Galerkin coarse operator } A_{l+1} = P_{l+1 \to l}^T A_l P_{l+1 \to l}$ -\State $l \leftarrow l + 1$ -\EndWhile -\State $\text{Factorize coarsest matrix } A_l \text{ using exact LU factorization or block Jacobi IC}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, pp. 9-10; IterMethBook_2ndEd.pdf.pdf, Section 13.6, pp. 455-463_ - -**amg-v-cycle-preconditioner-application** -$$ -\begin{algorithmic} -\State $u_l \leftarrow 0, \text{ given residual } r_l \text{ at level } l$ -\State $u_l \leftarrow u_l + \text{Smooth}_{\nu_1}(A_l, r_l) \quad \text{(Pre-smoothing via Chebyshev or Richardson iteration)}$ -\State $r_{l+1} = P_{l+1 \to l}^T (r_l - A_l u_l) \quad \text{(Restrict residual to coarse level)}$ -\If{$l+1 == l_{\text{coarsest}}$} -\State $e_{l+1} = A_{l_{\text{coarsest}}}^{-1} r_{l+1} \quad \text{(Direct solve via exact LU or 2 Krylov iterations of block Jacobi IC)}$ -\Else -\EndIf -\State $u_l \leftarrow u_l + P_{l+1 \to l} e_{l+1} \quad \text{(Prolong error correction to fine level)}$ -\State $u_l \leftarrow u_l + \text{Smooth}_{\nu_2}(A_l, r_l - A_l u_l) \quad \text{(Post-smoothing via Chebyshev or Richardson iteration)}$ -\Return $u_l$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 10; Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3, Fig. 2; IterMethBook_2ndEd.pdf.pdf, Section 13.4, p. 444_ - - -## 4. Known Pitfalls - -- **amg-setup-cost-overhead**: Preconditioner setup time (t_setup), which includes coarsening graph analysis, prolongation matrix construction, Galerkin products A_c = P^T A_f P, and Lanczos eigenvalue estimation, represents a substantial fraction (~50%) of total solution time. Re-building AMG hierarchies at every iteration without reusing setup across transient or quasi-Newton steps severely impairs computational efficiency. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.3, p. 22; Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section V.C, p. 8)_ -- **coarse-level-stiffness-degradation-in-cracking**: In phase-field brittle fracture and non-linear damage continuum mechanics, local material degradation causes stiffness entries to scale as (1 - d)^2 E. As damage d approaches 1, the condition number cond_2(M^-1 A) increases exponentially, degrading one-level preconditioner performance and increasing AMG iteration counts unless smoothed aggregation coarse-grid corrections prevent ill-conditioning. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.2.3, pp. 16-18)_ -- **element-stretching-convergence-degradation**: High aspect-ratio element stretching in anisotropic mesh discretizations degrades AMG coarse-grid convergence and increases condition numbers. Tuning coarsening thresholds and smoothing parameters for stretched element regions is required to preserve convergence robustness. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section V.D, p. 10)_ - -## References - -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf -- IterMethBook_2ndEd.pdf.pdf -- Trotter et al_2023_Targeting performance and user-friendliness.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/precond-domain-decomp.md b/packages/akms/src/akms/_bundled/global_nodes/precond-domain-decomp.md deleted file mode 100644 index b1092af..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/precond-domain-decomp.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -id: precond-domain-decomp -title: Domain Decomposition Preconditioners -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- preconditioner -- domain-decomposition -- schwarz -- BDDC -- FETI-DP -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-pcg-algorithm - type: feeds-into - weight: 0.5 -- to: precond-amg-theory - type: refines - weight: 0.7 -- to: precond-field-split-block - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Domain Decomposition Preconditioners - -## Summary - -Domain decomposition preconditioners divide large-scale computational domains into smaller, manageable subdomains to accelerate Krylov subspace iterative linear solvers (such as PCG or GMRES) on parallel distributed-memory architectures. Key paradigms include non-overlapping domain decomposition (such as Schur complement reduction and Balancing Domain Decomposition by Constraints [BDDC]) and overlapping Schwarz methods (such as Additive Schwarz [ASM] and Restricted Additive Schwarz [RASM]). - -## 1. Core Concept - -Domain decomposition preconditioners accelerate parallel iterative linear solvers for discretized boundary value problems by decomposing global domain mesh graphs into s subdomains. In overlapping Additive Schwarz Methods (ASM), local subproblems are solved on overlapping regions using restriction operators R_i and local sub-Jacobians J_i. Global updates are formed by prolonging and summing local solutions. To reduce parallel communication latency in high-performance computing, Restricted Additive Schwarz (RASM) applies non-overlapping prolongation operators \tilde{R}_i^T, eliminating interprocess message passing during interpolation. In non-overlapping domain decomposition, global systems are partitioned into subdomain interiors and shared interfaces, reducing equations to Schur complement interface systems S = A_{II} - A_{IE} A_{EE}^{-1} A_{EI}. Dual-primal and constraint-balancing methods (such as PCBDDC) enforce continuity across subdomain corners and edges, providing robust concurrency and algorithmic scalability across thousands of MPI processes. - -## 2. Mathematical Formulation - -**additive-schwarz-preconditioner** -$$ -P_{\text{1ASM}}^{-1} = \sum_{i=1}^s R_i^T J_i^{-1} R_i -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 3.2, p. 367; IterMethBook_2ndEd.pdf.pdf, Section 14.3, p. 488_ - -**restricted-additive-schwarz-rasm** -$$ -P_{\text{1RASM}}^{-1} = \sum_{i=1}^s \tilde{R}_i^T J_i^{-1} R_i -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 3.2, p. 367_ - -**additive-schwarz-iteration-update** -$$ -x^{(k+1)} = x^{(k)} + \sum_{i=1}^s R_i^T A_i^{-1} R_i (b - A x^{(k)}) -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 14.3, p. 488_ - -**domain-decomposition-schur-complement** -$$ -S = A_{II} - A_{IE} A_{EE}^{-1} A_{EI} -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 14.2, p. 477_ - -**Notation:** -x represents global solution vector; b represents global right-hand side vector; r represents global residual vector; R_i represents restriction operator for subdomain i; \tilde{R}_i^T represents restricted prolongation operator; J_i, A_i represent local subdomain matrices; s represents number of subdomains; S represents Schur complement matrix. - - -## 3. Algorithmic Implementation - -**additive-schwarz-preconditioned-krylov-step** -$$ -\begin{algorithmic} -\State $\text{Given global residual } r_k = b - A x_k \text{ at Krylov iteration } k$ -\For{$i = 1 \text{ to } s \quad \text{(parallel loop over subdomains } P_i\text{)}$} -\State $r_{i,\text{local}} = R_i r_k \quad \text{(restrict global residual to subdomain } \Omega_i\text{)}$ -\State $z_{i,\text{local}} = A_i^{-1} r_{i,\text{local}} \quad \text{(solve local subdomain problem via exact or ILU factorization)}$ -\State $z_{i,\text{global}} = R_i^T z_{i,\text{local}} \quad \text{(prolong local update to global space)}$ -\EndFor -\State $z_k = \sum_{i=1}^s z_{i,\text{global}} \quad \text{(accumulate preconditioned update vector)}$ -\Return $z_k$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 3.2, p. 367; IterMethBook_2ndEd.pdf.pdf, Section 14.3, p. 488_ - -**restricted-additive-schwarz-preconditioner-step** -$$ -\begin{algorithmic} -\State $\text{Given global residual } r_k = b - A x_k$ -\For{$i = 1 \text{ to } s \quad \text{(concurrent MPI processes)}$} -\State $r_{i,\text{local}} = R_i r_k \quad \text{(gather residual with overlap data from neighbors)}$ -\State $z_{i,\text{local}} = J_i^{-1} r_{i,\text{local}} \quad \text{(local subdomain linear solve)}$ -\State $z_{i,\text{global}} = \tilde{R}_i^T z_{i,\text{local}} \quad \text{(non-overlapping prolongation without communication)}$ -\EndFor -\State $z_k = \sum_{i=1}^s z_{i,\text{global}} \quad \text{(sum local updates)}$ -\Return $z_k$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 3.2, p. 367_ - - -## 4. Known Pitfalls - -- **rasm-communication-overhead-reduction**: Standard Additive Schwarz (ASM) requires interprocess MPI communication during both restriction (R_i) and prolongation (R_i^T) phases. Restricted Additive Schwarz (RASM) replaces R_i^T with non-overlapping operator \tilde{R}_i^T, eliminating interpolation communication overhead while improving Krylov convergence rates. _(Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 3.2, p. 367)_ -- **block-jacobi-communication-efficiency-tradeoff**: Block Jacobi preconditioning solves subproblems on localized domain partitions without subdomain overlap. While Block Jacobi minimizes communication overhead compared to overlapping Schwarz methods, it requires more Krylov iterations to converge as problem sizes scale, resulting in higher total execution times on moderate core counts. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.3.1, p. 21; Section 5.3.2, p. 23)_ -- **subdomain-solver-ill-conditioning-in-damage**: In non-linear fracture mechanics, localized stiffness loss causes local subdomain matrices A_i to become severely ill-conditioned or singular as damage d approaches 1. Solving local subdomain systems via incomplete factorizations (e.g. ILU or IC) without regularization or pivoting leads to local solver breakdown. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.2.3, p. 16; Section 5.3, p. 21)_ - -## References - -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- IterMethBook_2ndEd.pdf.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/precond-field-split-block.md b/packages/akms/src/akms/_bundled/global_nodes/precond-field-split-block.md deleted file mode 100644 index 0d98708..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/precond-field-split-block.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -id: precond-field-split-block -title: Field-Split & Block Preconditioners -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- preconditioner -- field-split -- schur-complement -- saddle-point -- block-precond -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-minres - type: feeds-into - weight: 0.5 -- to: solver-gmres-algorithm - type: feeds-into - weight: 0.5 -- to: precond-amg-theory - type: requires - weight: 1.0 -- to: pf-staggered-scheme - type: refines - weight: 0.7 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Field-Split & Block Preconditioners - -## Summary - -Field-split and block preconditioners decompose multi-physics, coupled, or block-structured linear systems—such as mixed displacement-damage phase-field fracture formulations and PDE-constrained KKT saddle-point systems—into individual field blocks. By approximating full coupled Jacobian matrices using uncoupled block-diagonal matrices \hat{K} = \text{diag}(K_{uu}, K_{dd}), block Jacobi preconditioners, or Schur complement projections, block preconditioning strategies isolate physical subproblems, lower memory overhead, and accelerate Krylov subspace iterative solvers (such as Conjugate Gradient, GMRES, or MINRES). - -## 1. Core Concept - -In coupled computational mechanics discretizations (such as vectorial mixed finite element phase-field models or PDE-constrained optimization), assembling and inverting full coupled tangent stiffness matrices is computationally expensive due to strong off-diagonal field coupling. Field-split and block preconditioning methods partition global linear systems into block subproblems corresponding to distinct physical variables (e.g., displacement u and damage d, or primal state, design, and Lagrange multipliers). Block-diagonal preconditioners approximate full stiffness matrices K = \begin{bmatrix} K_{uu} & K_{ud} \\ K_{du} & K_{dd} \end{bmatrix} by dropping off-diagonal coupling blocks, yielding uncoupled block-diagonal operators \hat{K} = \begin{bmatrix} K_{uu} & 0 \\ 0 & K_{dd} \end{bmatrix}. In block Jacobi preconditioning, individual diagonal block submatrices M_i are factorized independently using zero fill-in incomplete Cholesky IC(0) or ILU(0). In saddle-point systems arising from equality-constrained problems, Schur complement reduction condenses state equations to isolate interface or multiplier fields. - -## 2. Mathematical Formulation - -**uncoupled-block-diagonal-preconditioner** -$$ -\hat{K} = \begin{bmatrix} K_{uu} & 0 \\ 0 & K_{dd} \end{bmatrix} -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 2, p. 5; Wu et al. - 2020 - On the BFGS monolithic algorithm for the unified phase field damage theory.pdf, Section 3.1, p. 8_ - -**full-coupled-tangent-stiffness-matrix** -$$ -K = \begin{bmatrix} K_{uu} & K_{ud} \\ K_{du} & K_{dd} \end{bmatrix} -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 2, p. 5; Wu et al. - 2020 - On the BFGS monolithic algorithm for the unified phase field damage theory.pdf, Section 3.1, p. 8_ - -**block-jacobi-preconditioning-operator** -$$ -P_{\text{BJacobi}}^{-1} = \text{diag}(M_1^{-1}, M_2^{-1}, \dots, M_{N_p}^{-1}) -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.2.3, p. 15; Section 5.3.1, p. 21_ - -**saddle-point-block-system** -$$ -\begin{bmatrix} A & B \\ B^T & 0 \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} b \\ c \end{bmatrix} -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 8.4, p. 268_ - -**Notation:** -K represents global coupled tangent stiffness matrix; \hat{K} represents uncoupled block-diagonal preconditioner matrix; K_{uu}, K_{dd} represent displacement and damage block matrices; K_{ud}, K_{du} represent cross-field coupling matrices; M_i represents local diagonal block matrix; P_{\text{BJacobi}}^{-1} represents block Jacobi preconditioner operator; A, B represent saddle-point block submatrices. - - -## 3. Algorithmic Implementation - -**block-diagonal-field-split-preconditioner-apply** -$$ -\begin{algorithmic} -\State $\text{Given residual vector } r = [r_u; r_d] \text{ for displacement and damage fields}$ -\State $\text{Apply displacement block preconditioner } z_u = K_{uu}^{-1} r_u \text{ (exact LU, AMG, or Krylov solve)}$ -\State $\text{Apply damage block preconditioner } z_d = K_{dd}^{-1} r_d \text{ (exact LU or multigrid solve)}$ -\State $z = [z_u; z_d] \quad \text{(assemble preconditioned search direction vector)}$ -\Return $z$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 2, p. 5; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 1, p. 3_ - -**block-jacobi-ic-preconditioner-apply** -$$ -\begin{algorithmic} -\State $\text{Given global linear system residual vector } r = [r_1; r_2; \dots; r_{N_p}]$ -\For{$i = 1 \text{ to } N_p \quad \text{(parallel loop over local processes or field blocks)}$} -\State $z_i = M_i^{-1} r_i \quad \text{where } M_i \approx L_i L_i^T \text{ via zero fill-in incomplete Cholesky IC(0)}$ -\EndFor -\State $z = [z_1; z_2; \dots; z_{N_p}]$ -\Return $z$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.2.3, p. 15; Section 5.3.1, p. 21_ - - -## 4. Known Pitfalls - -- **block-diagonal-coupling-omission-degradation**: Omitting off-diagonal cross-coupling blocks K_{ud} and K_{du} in uncoupled block-diagonal preconditioner \hat{K} = \text{diag}(K_{uu}, K_{dd}) ignores strong physical interaction between displacement and damage fields in highly non-linear phase-field fracture regimes. While uncoupled block matrices serve effectively as initial inverse Hessian scaling in quasi-Newton L-BFGS solvers, using modified Newton with \hat{K} as a standalone linear solver leads to slow convergence or solver stagnation during rapid crack propagation. _(Source: Wu et al. - 2020 - On the BFGS monolithic algorithm for the unified phase field damage theory.pdf, Section 3.1, p. 8; Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 2, p. 5)_ -- **block-jacobi-fill-in-level-tradeoff**: Solving local subproblem diagonal blocks M_i in block Jacobi preconditioning using zero fill-in factorizations (IC(0) or ILU(0)) provides low setup cost but higher iteration counts compared to complete LU/Cholesky factorizations. Increasing fill-in levels ILU(n)/IC(n) approaches an exact preconditioner but increases memory consumption and local setup time. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.3.1, p. 21)_ -- **saddle-point-indefiniteness-solver-breakdown**: Saddle-point block coefficient matrices with zero diagonal blocks for Lagrange multiplier constraints are inherently indefinite, preventing direct application of standard Preconditioned Conjugate Gradient (PCG) solvers without Schur complement transformations or MINRES/GMRES Krylov solvers. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 8.4, p. 268; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 6.1, p. 388)_ - -## References - -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf -- Wu et al. - 2020 - On the BFGS monolithic algorithm for the unified phase field damage theory.pdf -- IterMethBook_2ndEd.pdf.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/precond-geometric-mg.md b/packages/akms/src/akms/_bundled/global_nodes/precond-geometric-mg.md deleted file mode 100644 index 3d7c791..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/precond-geometric-mg.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: precond-geometric-mg -title: Geometric & p-Multigrid -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- GMG -- p-multigrid -- geometric-multigrid -- hierarchical -- brown-2022 -status: established -confidence: 0.9 -source: hybrid -edges: -- to: precond-amg-theory - type: refines - weight: 0.7 -- to: solver-pcg-algorithm - type: feeds-into - weight: 0.5 -- to: solver-matrix-free-operator - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Geometric & p-Multigrid - -## Summary - -Geometric and p-multigrid methods accelerate iterative linear solvers for discretized partial differential equations by constructing hierarchical coarsening spaces. While traditional geometric multigrid (GMG) relies on nested spatial mesh refinements, p-multigrid (p-MG) constructs coarse spaces by reducing the polynomial degree of high-order finite element spaces (e.g., Q_p down to linear Q_1) on a fixed mesh geometry. When combined with matrix-free partial assembly for fine-level operators, Chebyshev polynomial smoothers, and algebraic multigrid (AMG) or direct solvers on the coarsest linear level, matrix-free p-multigrid achieves optimal algorithmic scaling and high throughput on parallel CPU and GPU architectures. - -## 1. Core Concept - -High-order finite element discretizations (Q_p elements for p >= 2) achieve high spatial accuracy per degree of freedom, but full assembly of sparse tangent stiffness matrices causes severe memory consumption and memory bandwidth bottlenecks. Matrix-free p-multigrid (p-MG) circumvents sparse matrix storage by evaluating element operations on-the-fly via quadrature-point tensor contractions (partial assembly). In p-MG, error smoothing on high-order fine spaces (Q_p) is performed using 2nd-order Chebyshev-polynomial Jacobi iterations targeting upper eigenspectrum bounds estimated via Lanczos iterations. Coarse-grid restriction P_{c \to f}^T and prolongation P_{c \to f} map solution residuals between polynomial degree levels. Once coarsened down to the linear element level (Q_1), operator stiffness matrices are assembled into sparse CSR matrices and solved via algebraic multigrid (e.g., hypre BoomerAMG or PETSc GAMG) or direct factorization. - -## 2. Mathematical Formulation - -**p-mg-galerkin-operator** -$$ -A_c = P_{c \to f}^T A_f P_{c \to f} -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3_ - -**chebyshev-jacobi-smoother-operator** -$$ -u^{(l+1)} = u^{(l)} + \hat{M}^{-1} (b - A_f u^{(l)}) -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3_ - -**matrix-free-operator-action** -$$ -A u = \sum_e \mathcal{P}^T \mathcal{E}^T B^T D \mathcal{E} \mathcal{P} u -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section II.B, p. 2, Fig. 1_ - -**Notation:** -A_f, A_c represent fine and coarse matrix-free operators; P_{c \to f} represents prolongation operator from coarse to fine level; u_f, u_c represent fine and coarse displacement vectors; \hat{M}^{-1} represents 2nd-order Chebyshev polynomial smoother; \lambda_{\max} represents maximum eigenvalue of preconditioned operator; Q_p represents tensor-product element space of degree p. - - -## 3. Algorithmic Implementation - -**matrix-free-p-multigrid-v-cycle** -$$ -\begin{algorithmic} -\State $\text{Given fine-grid residual } r_f = b - A_f u_f \text{ on high-order space } Q_p$ -\State $u_f \leftarrow u_f + \hat{M}^{-1} (b - A_f u_f) \quad \text{(Pre-smoothing via Chebyshev/Jacobi iteration)}$ -\State $r_c = P_{c \to f}^T (b - A_f u_f) \quad \text{(Restrict residual to coarse polynomial level } Q_c\text{)}$ -\If{$\text{Coarse space } Q_c \text{ is linear } Q_1$} -\State $\text{Assemble } Q_1 \text{ sparse CSR matrix } A_1 \text{ and solve } A_1 e_1 = r_c \text{ via AMG (hypre BoomerAMG) or Cholesky}$ -\Else -\EndIf -\State $u_f \leftarrow u_f + P_{c \to f} e_c \quad \text{(Prolong error correction to fine grid)}$ -\State $u_f \leftarrow u_f + \hat{M}^{-1} (b - A_f u_f) \quad \text{(Post-smoothing via Chebyshev/Jacobi iteration)}$ -\Return $u_f$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3, Fig. 2_ - - -## 4. Known Pitfalls - -- **amg-coarse-grid-setup-latency-bottleneck**: In matrix-free p-multigrid solvers, while fine-level Q_p operator evaluations and Chebyshev smoothing execute rapidly via GPU tensor contractions, assembling and setting up the Q_1 coarse-grid AMG preconditioner (e.g., BoomerAMG) accounts for more than half of total preconditioner setup time despite Q_1 having 8x fewer degrees of freedom than Q_2. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section V.C, p. 6, Fig. 10)_ -- **element-stretching-convergence-degradation**: High aspect-ratio element stretching degrades p-multigrid coarse-grid convergence and inflates iteration counts (e.g., condition numbers rising from ~14 to over 400 for 4:1 aspect ratios). Custom tuning of AMG coarsening thresholds and smoother relaxation for stretched element regions is required to maintain convergence robustness. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section V.D, p. 6, Table III)_ -- **unstructured-mesh-hierarchy-generation-limitation**: Geometric multigrid (GMG) requires nested sequences of refined unstructured meshes, which are difficult and non-trivial to generate automatically for complex 3D engineering geometries. This spatial hierarchy requirement limits standard GMG applicability compared to p-multigrid or algebraic multigrid (AMG). _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 1, p. 3)_ - -## References - -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- Trotter et al_2023_Targeting performance and user-friendliness.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/precond-gpu-alternatives.md b/packages/akms/src/akms/_bundled/global_nodes/precond-gpu-alternatives.md deleted file mode 100644 index 71771f1..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/precond-gpu-alternatives.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -id: precond-gpu-alternatives -title: GPU-Friendly Preconditioner Alternatives -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- preconditioner -- GPU -- chebyshev -- SPAI -- multicolor -- l1-jacobi -status: established -confidence: 0.9 -source: hybrid -edges: -- to: precond-ichol-ilu - type: contradicts - weight: 0.0 -- to: precond-jacobi-block-jacobi - type: refines - weight: 0.7 -- to: solver-pcg-algorithm - type: feeds-into - weight: 0.5 -- to: precond-amg-gpu - type: refines - weight: 0.7 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# GPU-Friendly Preconditioner Alternatives - -## Summary - -GPU-friendly preconditioner alternatives replace traditional sequential incomplete factorizations (such as ILU and incomplete Cholesky) with highly parallel operators that exploit high memory bandwidth and fine-grained concurrency on SIMD/GPU hardware. Key alternatives include Jacobi and block Jacobi scaling, Chebyshev polynomial smoothers, parallel Richardson relaxation, sparse approximate inverses (SPAI), and multi-color (Red-Black) relaxation schemes. - -## 1. Core Concept - -Standard incomplete lower-upper (ILU) and incomplete Cholesky (IC) factorizations rely on forward and backward triangular solves that contain intrinsic data dependencies, creating severe performance bottlenecks on massively parallel GPU architectures. To maximize computational throughput, GPU-friendly preconditioners prioritize matrix-vector products and element-wise vector operations over triangular solves. Point-Jacobi preconditioning (P = diag(A)^-1) and block Jacobi preconditioning with local IC(0)/ILU(0) sub-solvers offer embarrassingly parallel application without interprocess communication during diagonal inversion. In multigrid V-cycles, Chebyshev polynomial smoothers (e.g., 2nd-order Chebyshev polynomials with Jacobi scaling) damp high-frequency errors using matrix-vector actions targeting upper eigenspectrum bounds estimated via Lanczos or CG iterations. Sparse Approximate Inverse (SPAI) methods compute explicit sparse inverse matrices M approx A^-1 via Frobenius norm minimization, replacing triangular solves with sparse matrix-vector multiplications (SpMV). Multi-color (Red-Black) reorderings decouple grid dependencies into color sets for parallel relaxation, though reordering alters the iteration matrix and typically increases iteration counts compared to natural orderings. - -## 2. Mathematical Formulation - -**jacobi-preconditioning-matrix** -$$ -P = \text{diag}(A)^{-1} -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 9; Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf, Section 4.2, p. 5_ - -**chebyshev-polynomial-smoother** -$$ -u^{(l+1)} = u^{(l)} + \hat{M}^{-1} (b - A u^{(l)}) -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 10_ - -**block-jacobi-subdomain-operator** -$$ -P_{\text{BJacobi}}^{-1} = \text{diag}(M_1^{-1}, M_2^{-1}, \dots, M_{s}^{-1}) -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 9; Section 5.3.1, p. 21_ - -**sparse-approximate-inverse-spai** -$$ -\min_{M \in \mathcal{S}} \|I - A M\|_F^2 = \sum_{j=1}^n \min_{m_j \in \mathcal{S}_j} \|e_j - A m_j\|_2^2 -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 10.5, pp. 336-338_ - -**Notation:** -A represents global assembled stiffness or Hessian matrix; P represents Jacobi diagonal preconditioner; \hat{M}^{-1} represents Chebyshev polynomial preconditioning operator; M_i represents local subdomain matrix block; M represents sparse approximate inverse matrix; \lambda_{\max} represents maximum eigenvalue estimate computed via Lanczos or CG. - - -## 3. Algorithmic Implementation - -**parallel-jacobi-pncg-apply** -$$ -\begin{algorithmic} -\State $g_{k+1}, P_{k+1} \leftarrow \text{Compute gradient } g_{k+1} = \nabla E(x_{k+1}) \text{ and Jacobi preconditioner } P_{k+1} = \text{diag}(H_{k+1})^{-1} \text{ in parallel}$ -\State $y_k \leftarrow g_{k+1} - g_k$ -\State $\beta_k^{\text{DK}} \leftarrow \frac{g_{k+1}^T P_{k+1} y_k}{y_k^T p_k} - \frac{y_k^T P_{k+1} y_k}{y_k^T p_k} \frac{p_k^T g_{k+1}}{y_k^T p_k}$ -\State $p_{k+1} \leftarrow -P_{k+1} g_{k+1} + \beta_k^{\text{DK}} p_k$ -\end{algorithmic} -$$ -Taichi Mapping: Implemented natively in Taichi using MeshTaichi for parallel element assembly of diagonal Hessian terms, Jacobi preconditioner inversion, and parallel vector dot products on GPUs. -_Source: Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf, Section 4.2, p. 5, Algorithm 1_ - -**chebyshev-polynomial-smoothing-step** -$$ -\begin{algorithmic} -\State $\text{Estimate maximum eigenvalue } \lambda_{\max}(M^{-1} A) \text{ using 10 Lanczos or CG iterations during setup}$ -\State $\text{Set upper polynomial spectral bound } [\lambda_{\min}, \lambda_{\max}] \leftarrow [0.1 \lambda_{\max}, 1.1 \lambda_{\max}]$ -\For{$l = 1 \text{ to } \nu \quad \text{(smoothing iterations)}$} -\State $r^{(l)} = b - A u^{(l)} \quad \text{(evaluate residual via matrix-free or SpMV operator)}$ -\State $u^{(l+1)} = u^{(l)} + \hat{M}^{-1} r^{(l)} \quad \text{(apply Chebyshev polynomial scaling with diagonal Jacobi inverse)}$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 10_ - - -## 4. Known Pitfalls - -- **jacobi-poor-condition-number-reduction**: Point-Jacobi preconditioning (P = diag(A)^-1) is trivial to invert and embarrassingly parallel on vector and GPU hardware, but provides weak condition number reduction for ill-conditioned elliptic or elasticity problems. In phase-field fracture, Jacobi preconditioning requires 5-10x more CG iterations to converge compared to algebraic multigrid, increasing total time to solution despite low per-iteration setup costs. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.2.3, pp. 15-18; Section 5.3.1, p. 21)_ -- **multicolor-gauss-seidel-iteration-penalty**: Multi-color reordering (such as Red-Black Gauss-Seidel) enables fine-grained parallel relaxation by grouping independent nodes into color sets. However, reordering the global matrix changes the iteration matrix, typically increasing the total number of iterations required for Krylov convergence compared to natural orderings. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 10.2, p. 298; Section 13.4.1, p. 445)_ -- **spai-high-setup-cost-overhead**: Computing explicit Sparse Approximate Inverse (SPAI) preconditioners M \approx A^-1 requires solving independent unconstrained Frobenius-norm minimization problems for each column. If the target sparsity pattern S is too dense or recomputed at every non-linear step, setup time dominates overall solution time. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 10.5, pp. 336-338; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.3.1, p. 22)_ - -## References - -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf -- Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf -- IterMethBook_2ndEd.pdf.pdf -- Trotter et al_2023_Targeting performance and user-friendliness.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/precond-ichol-ilu.md b/packages/akms/src/akms/_bundled/global_nodes/precond-ichol-ilu.md deleted file mode 100644 index 7036397..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/precond-ichol-ilu.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: precond-ichol-ilu -title: Incomplete Cholesky / ILU Factorization -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- preconditioner -- IC -- ILU -- incomplete-factorization -- GPU-challenge -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-pcg-algorithm - type: feeds-into - weight: 0.5 -- to: solver-direct - type: refines - weight: 0.7 -- to: precond-gpu-alternatives - type: contradicts - weight: 0.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Incomplete Cholesky / ILU Factorization - -## Summary - -Incomplete Cholesky (IC) and Incomplete LU (ILU) factorizations compute sparse approximations L \tilde{U} \approx A (or \tilde{L} \tilde{L}^T \approx A for symmetric positive-definite matrices) by discarding fill-in entries outside a prescribed sparsity pattern or below a drop tolerance threshold. Used extensively as standalone preconditioners or as local block solvers in block Jacobi and domain decomposition frameworks, IC and ILU significantly reduce Krylov iteration counts compared to point-Jacobi scaling, though forward and backward triangular solves introduce sequential dependency bottlenecks on parallel computing architectures. - -## 1. Core Concept - -Incomplete factorizations modify Gaussian elimination to construct sparse lower and upper triangular factors \tilde{L} and \tilde{U} such that error matrix R = \tilde{L} \tilde{U} - A meets specific sparsity or threshold constraints. Zero fill-in factorizations (ILU(0) and IC(0)) restrict \tilde{L} and \tilde{U} strictly to the nonzero pattern of original matrix A, avoiding dynamic memory allocation during setup. Higher-order level-of-fill variants (ILU(p)) and threshold-based strategies (ILUT) allow fill-in based on topological graph paths or numerical magnitude, approaching exact direct LU/Cholesky factorizations as fill levels increase. For symmetric positive-definite systems arising in finite element discretizations (such as monolithic phase-field fracture or linear elasticity), IC(0) provides a positive-definite preconditioner that reduces Conjugate Gradient iteration counts by approximately 4-5x compared to point-Jacobi preconditioning. However, applying preconditioner solve M^{-1} r = \tilde{U}^{-1} \tilde{L}^{-1} r requires forward and backward substitution steps with inherently sequential, row-wise recurrences, creating fine-grained data dependencies that limit parallel scaling on vector and parallel hardware. - -## 2. Mathematical Formulation - -**ilu0-split-preconditioning-matrix** -$$ -M = (D - E) D^{-1} (D - F) -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 10.3.2, p. 308_ - -**general-ikj-gaussian-elimination-ilu** -$$ -a_{ij} \leftarrow a_{ij} - a_{ik} a_{kj} \quad \text{for } (i, j) \in \text{NZ}(A) -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 10.3.2, p. 307_ - -**incomplete-cholesky-zero-fill** -$$ -M = \tilde{L} \tilde{L}^T -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 10; IterMethBook_2ndEd.pdf.pdf, Section 10.5, p. 332_ - -**Notation:** -A represents global assembled stiffness matrix; \tilde{L}, \tilde{U} represent sparse incomplete lower and upper triangular factor matrices; R represents factorization error residual matrix; D represents recursively updated diagonal matrix; -E, -F represent strict lower and upper triangular parts of A; \tau represents drop tolerance threshold parameter; p, lfil represent fill-in level parameters. - - -## 3. Algorithmic Implementation - -**ikj-incomplete-lu-factorization-ilu0** -$$ -\begin{algorithmic} -\State $\text{Given matrix } A \text{ with nonzero sparsity pattern } \text{NZ}(A)$ -\For{$i = 2 \text{ to } n$} -\For{$k = 1 \text{ to } i - 1 \text{ and } (i, k) \in \text{NZ}(A)$} -\State $a_{ik} \leftarrow a_{ik} / a_{kk}$ -\For{$j = k + 1 \text{ to } n \text{ and } (i, j) \in \text{NZ}(A)$} -\State $a_{ij} \leftarrow a_{ij} - a_{ik} a_{kj}$ -\EndFor -\EndFor -\EndFor -\Return $\tilde{L} = \text{tril}(A, -1) + I, \quad \tilde{U} = \text{triu}(A)$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: IterMethBook_2ndEd.pdf.pdf, Section 10.3.2, p. 307, Algorithm 10.3_ - -**block-jacobi-ic0-preconditioner-solve** -$$ -\begin{algorithmic} -\State $\text{Factorize local diagonal blocks } M_i = \tilde{L}_i \tilde{L}_i^T \text{ using zero fill-in Incomplete Cholesky IC(0)}$ -\For{$i = 1 \text{ to } N_p \quad \text{(parallel subdomain loop)}$} -\State $\text{Solve } \tilde{L}_i y_i = r_i \text{ via forward substitution}$ -\State $\text{Solve } \tilde{L}_i^T z_i = y_i \text{ via backward substitution}$ -\EndFor -\State $z = [z_1; z_2; \dots; z_{N_p}]$ -\Return $z$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 10; Section 5.3.1, p. 21_ - - -## 4. Known Pitfalls - -- **sequential-triangular-solve-parallel-bottleneck**: Applying incomplete factorization preconditioners M^{-1} r = \tilde{U}^{-1} \tilde{L}^{-1} r requires forward and backward triangular solves with recursive, row-by-row data dependencies. These sequential dependencies limit fine-grained concurrency and vectorization on parallel hardware architectures, making point-Jacobi or polynomial smoothers more effective on massively parallel vector processors. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 10.3, p. 301; Section 12.1, p. 376; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.3.2, p. 23)_ -- **zero-pivot-and-unstable-ilut-factorization**: Incomplete factorizations applied to non-M-matrices or non-positive-definite systems can encounter zero or near-zero pivot elements a_{kk} \approx 0 during elimination, producing unstable factors where \|\tilde{U}^{-1} \tilde{L}^{-1}\| is extremely large and causing outer Krylov iterations to diverge. Pivoting strategies (ILUTP) or diagonal shifts are required to maintain stability. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 10.4.3, p. 328; Section 10.4.4, p. 327)_ - -## References - -- IterMethBook_2ndEd.pdf.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/precond-jacobi-block-jacobi.md b/packages/akms/src/akms/_bundled/global_nodes/precond-jacobi-block-jacobi.md deleted file mode 100644 index f00d3eb..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/precond-jacobi-block-jacobi.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: precond-jacobi-block-jacobi -title: Jacobi & Block Jacobi Preconditioners -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- preconditioner -- jacobi -- block-jacobi -- GPU -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-pcg-algorithm - type: feeds-into - weight: 0.5 -- to: solver-gmres-algorithm - type: feeds-into - weight: 0.5 -- to: precond-amg-theory - type: contradicts - weight: 0.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Jacobi & Block Jacobi Preconditioners - -## Summary - -Jacobi and block Jacobi preconditioners accelerate Krylov subspace iterative solvers (such as PCG and GMRES) by extracting diagonal or block-diagonal submatrices from global finite element stiffness matrices. While point-Jacobi preconditioning scales diagonal entries with near-zero setup cost, block Jacobi preconditioning captures localized field connectivity within subdomain partitions via local incomplete Cholesky or LU factorizations. Both approaches offer fine-grained parallel concurrency, though point-Jacobi exhibits weak condition number reduction compared to multi-level algebraic multigrid solvers. - -## 1. Core Concept - -Preconditioning accelerates iterative linear solvers for discretized partial differential equations by transforming ill-conditioned coefficient matrices A into preconditioned systems M^-1 A with clustered eigenspectra. Point-Jacobi preconditioning sets M = diag(A), providing an embarrassingly parallel operator where inversion requires simply taking entrywise reciprocals M^-1_ii = 1 / A_ii with negligible setup time (~1% of total solution time). However, in elasticity and phase-field fracture mechanics, point-Jacobi provides weak condition number reduction, leading to high Conjugate Gradient (CG) iteration counts. Block Jacobi preconditioning improves robustness by partitioning domain degrees of freedom into local diagonal blocks M_i = A_i (corresponding to parallel process or mesh partitions). Each local block submatrix M_i is factorized independently using zero fill-in incomplete Cholesky IC(0) or incomplete LU ILU(0). By incorporating off-diagonal coupling within local subdomains, block Jacobi reflects the nonzero structure and physical field coupling of the global system, reducing CG iterations by 3-4x compared to scalar Jacobi while preserving high parallel efficiency across distributed-memory MPI processes. - -## 2. Mathematical Formulation - -**scalar-jacobi-preconditioning-operator** -$$ -P_{\text{Jacobi}}^{-1} = \text{diag}(A)^{-1} = \text{diag}\left(\frac{1}{A_{11}}, \frac{1}{A_{22}}, \dots, \frac{1}{A_{nn}}\right) -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 9; IterMethBook_2ndEd.pdf.pdf, Section 4.1, p. 105_ - -**block-jacobi-preconditioning-operator** -$$ -P_{\text{BJacobi}}^{-1} = \text{diag}(M_1^{-1}, M_2^{-1}, \dots, M_{s}^{-1}) -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 9; IterMethBook_2ndEd.pdf.pdf, Section 4.2, p. 108_ - -**damped-jacobi-iteration** -$$ -x^{(k+1)} = (1 - \omega) x^{(k)} + \omega D^{-1} (b - (A - D) x^{(k)}) -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 4.1, p. 105; Section 13.4, p. 445_ - -**Notation:** -A represents global assembled stiffness matrix; D = diag(A) represents diagonal matrix; P_{\text{Jacobi}}^{-1} represents scalar Jacobi inverse preconditioner; P_{\text{BJacobi}}^{-1} represents block Jacobi inverse preconditioner operator; M_i represents local process diagonal block matrix; L_i represents lower triangular factor matrix from local IC(0); \omega represents damping weight parameter. - - -## 3. Algorithmic Implementation - -**parallel-scalar-jacobi-apply** -$$ -\begin{algorithmic} -\State $\text{Given linear system residual } r_k = b - A x_k$ -\For{$i = 1 \text{ to } n \quad \text{(embarrassingly parallel loop)}$} -\State $z_i = \frac{r_{k,i}}{A_{ii}} \quad \text{(entrywise diagonal reciprocal multiplication)}$ -\EndFor -\Return $z_k$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 9; Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf, Section 4.2, p. 5_ - -**block-jacobi-ic-apply** -$$ -\begin{algorithmic} -\State $\text{Extract local subdomain diagonal blocks } M_i = A_i \text{ for process } i = 1, \dots, s$ -\State $\text{Factorize } M_i \approx \tilde{L}_i \tilde{L}_i^T \text{ using zero fill-in Incomplete Cholesky IC(0)}$ -\For{$i = 1 \text{ to } s \quad \text{(concurrent MPI process loop)}$} -\State $z_{i,\text{local}} = (\tilde{L}_i \tilde{L}_i^T)^{-1} r_{i,\text{local}} \quad \text{(solve local block problem via forward/backward substitution)}$ -\EndFor -\State $z_k = [z_{1,\text{local}}; z_{2,\text{local}}; \dots; z_{s,\text{local}}] \quad \text{(assemble global preconditioned vector)}$ -\Return $z_k$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 9; Section 5.3.1, p. 21_ - - -## 4. Known Pitfalls - -- **jacobi-weak-condition-number-reduction**: Point-Jacobi preconditioning (P = diag(A)^-1) requires minimal setup time (t_setup ~ 1%), but provides weak preconditioning power for ill-conditioned elasticity and phase-field fracture systems. In 2D phase-field fracture simulations, Jacobi-preconditioned CG required 593-920 iterations per time step compared to 152-202 for block Jacobi IC and 75-91 for AMG, resulting in significantly higher total solution times. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.2.3, pp. 15-18)_ -- **block-jacobi-subdomain-scaling-communication-tradeoff**: As the number of MPI processes scales to thousands, the subdomain block sizes m_i shrink, causing block Jacobi preconditioning to lose global coupling information and approach scalar Jacobi behavior. While block Jacobi exhibits high parallel efficiency (~87-97% on 1008 cores) due to localized block solves without interprocess overlap communication, iteration counts increase with fine mesh partitioning unless combined with coarse-grid corrections. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.3.2, pp. 23-25; IterMethBook_2ndEd.pdf.pdf, Section 14.3, p. 488)_ - -## References - -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- IterMethBook_2ndEd.pdf.pdf -- Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-bicgstab-algorithm.md b/packages/akms/src/akms/_bundled/global_nodes/solver-bicgstab-algorithm.md deleted file mode 100644 index 0ced020..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-bicgstab-algorithm.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -id: solver-bicgstab-algorithm -title: BiCGSTAB for Non-Symmetric Systems -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- BiCGSTAB -- krylov -- non-symmetric -- IDR -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-cg-algorithm - type: refines - weight: 0.7 -- to: solver-gmres-algorithm - type: contradicts - weight: 0.0 -- to: solver-pcg-algorithm - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# BiCGSTAB for Non-Symmetric Systems - -## Summary - -The Biconjugate Gradient Stabilized (BiCGSTAB) method is a transpose-free Krylov subspace iterative algorithm for solving large, sparse, non-symmetric linear systems Ax = b. Developed by van der Vorst to overcome the irregular convergence and transpose matrix-vector multiplication overhead of standard Biconjugate Gradient (BiCG) and Conjugate Gradient Squared (CGS), BiCGSTAB combines BiCG polynomial updates with local steepest-descent residual minimization steps, requiring two matrix-vector products per iteration. - -## 1. Core Concept - -BiCGSTAB solves non-symmetric linear systems arising in fluid-structure interaction, advection-diffusion PDEs, and linearized PDE-constrained optimization without evaluating transpose matrix-vector operations A^T v. At each iteration, BiCGSTAB updates solution vector x_{j+1} in two distinct phases: first, a standard BiCG step using step length \alpha_j along direction p_j yields an intermediate residual s_j = r_j - \alpha_j A p_j; second, a GMRES-like local residual minimization step scales s_j by parameter \omega_j = (A s_j, s_j) / (A s_j, A s_j), producing a smooth, stabilized residual trajectory r_{j+1} = s_j - \omega_j A s_j. By avoiding explicit transpose operations, BiCGSTAB reduces computational cost per step compared to BiCG while providing smoother convergence profiles than CGS. - -## 2. Mathematical Formulation - -**bicgstab-step-length-alpha** -$$ -\alpha_j = \frac{(r_j, r_0^*)}{(A p_j, r_0^*)} -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 7.4.2, p. 247_ - -**bicgstab-residual-vector-update** -$$ -s_j = r_j - \alpha_j A p_j, \quad r_{j+1} = s_j - \omega_j A s_j -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 7.4.2, p. 247_ - -**bicgstab-omega-parameter** -$$ -\omega_j = \frac{(A s_j, s_j)}{(A s_j, A s_j)} -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 7.4.2, p. 246_ - -**bicgstab-solution-update** -$$ -x_{j+1} = x_j + \alpha_j p_j + \omega_j s_j -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 7.4.2, p. 247_ - -**Notation:** -A represents global non-symmetric coefficient matrix; x represents solution vector; b represents right-hand side vector; r_j represents residual vector at step j; r_0^* represents shadow test vector; p_j represents search direction vector; s_j represents intermediate residual vector; \alpha_j represents BiCG step parameter; \omega_j represents residual minimization parameter; \beta_j represents momentum weighting parameter. - - -## 3. Algorithmic Implementation - -**bicgstab-algorithm** -$$ -\begin{algorithmic} -\State $x_0 \leftarrow \text{Initial guess}, \quad r_0 = b - A x_0, \quad r_0^* \leftarrow \text{Arbitrary shadow vector (e.g., } r_0\text{)}, \quad p_0 = r_0$ -\For{$j = 0, 1, 2, \dots \text{ until } \|r_j\|_2 < \text{tol}$} -\State $\alpha_j \leftarrow \frac{(r_j, r_0^*)}{(A p_j, r_0^*)}$ -\State $s_j \leftarrow r_j - \alpha_j A p_j$ -\State $\omega_j \leftarrow \frac{(A s_j, s_j)}{(A s_j, A s_j)}$ -\State $x_{j+1} \leftarrow x_j + \alpha_j p_j + \omega_j s_j$ -\State $r_{j+1} \leftarrow s_j - \omega_j A s_j$ -\State $\beta_j \leftarrow \frac{(r_{j+1}, r_0^*)}{(r_j, r_0^*)} \frac{\alpha_j}{\omega_j}$ -\State $p_{j+1} \leftarrow r_{j+1} + \beta_j (p_j - \omega_j A p_j)$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: IterMethBook_2ndEd.pdf.pdf, Section 7.4.2, p. 247, Algorithm 7.7; Xue et al_2023_JAX-FEM.pdf, Section 5, p. 11_ - - -## 4. Known Pitfalls - -- **bicgstab-breakdown-zero-scalar-products**: BiCGSTAB experiences breakdown or severe numerical instability when inner product (r_j, r_0*) = 0 or denominator (A p_j, r_0*) = 0 occurs before convergence. This breakdown stems from the underlying Lanczos or BiCG biorthogonalization process failing. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 7.4.2, p. 247; Section 7.5, p. 254)_ -- **bicgstab-stagnation-omega-zero**: The local residual minimization parameter omega_j = (A s_j, s_j) / (A s_j, A s_j) becomes zero when intermediate vector A s_j is orthogonal to s_j. When omega_j = 0, solution iterates x_{j+1} stop making progress, causing algorithm stagnation. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 7.4.2, p. 246; Section 7.5, p. 254)_ - -## References - -- IterMethBook_2ndEd.pdf.pdf -- Xue et al_2023_JAX-FEM.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-cg-algorithm.md b/packages/akms/src/akms/_bundled/global_nodes/solver-cg-algorithm.md deleted file mode 100644 index 05efc05..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-cg-algorithm.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -id: solver-cg-algorithm -title: 'Conjugate Gradient: Algorithm & Theory' -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- CG -- krylov -- hestenes-stiefel -- SPD -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-pcg-algorithm - type: refines - weight: 0.7 -- to: solver-direct - type: contradicts - weight: 0.0 -- to: solver-gmres-algorithm - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Conjugate Gradient: Algorithm & Theory - -## Summary - -The Conjugate Gradient (CG) algorithm is a Krylov subspace iterative solver for large, sparse, symmetric positive definite (SPD) linear systems Ax = b. Developed by Hestenes and Stiefel, CG computes A-conjugate search directions through Gram-Schmidt orthogonalization of residual vectors, minimizing the A-norm of the solution error at each iteration. Operating with three vector update operations (AXPYs), two inner products, and one matrix-vector product per iteration, CG avoids dense matrix inversions while achieving superlinear convergence. - -## 1. Core Concept - -Conjugate Gradient solves symmetric positive-definite linear systems arising from finite element discretizations of elliptic PDEs, elastodynamics, and monolithic phase-field fracture formulations. Unlike general Krylov methods like GMRES that store full Arnoldi basis sets, CG exploits the symmetry and positive definiteness of A to construct short three-term recurrences where consecutive search directions p_k are A-conjugate (p_i^T A p_j = 0 for i != j). At each iteration k, CG minimizes the energy norm (A-norm) of the error ||x* - x_k||_A over the Krylov subspace x_0 + K_k(A, r_0). Each iteration computes one matrix-vector multiplication A p_k, two vector dot products, and three vector updates (AXPYs) for solution iterate x_{k+1}, residual r_{k+1}, and direction p_{k+1}. - -## 2. Mathematical Formulation - -**cg-step-length-alpha** -$$ -\alpha_k = \frac{r_k^T r_k}{p_k^T A p_k} -$$ -_Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.1, p. 242; IterMethBook_2ndEd.pdf.pdf, Section 6.1, p. 214_ - -**cg-momentum-beta** -$$ -\beta_k = \frac{r_{k+1}^T r_{k+1}}{r_k^T r_k} -$$ -_Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.1, p. 242_ - -**cg-error-a-norm-minimization** -$$ -\|x^* - x_k\|_A = \min_{q \in \mathcal{P}_{k-1}} \|(I - A q(A)) d_0\|_A -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Lemma 6.28, p. 214_ - -**Notation:** -A represents global symmetric positive definite stiffness/coefficient matrix; x_k represents solution vector at iteration k; b represents load/right-hand side vector; r_k represents residual vector b - A x_k; p_k represents A-conjugate search direction vector; \alpha_k represents step size scalar; \beta_k represents orthogonalization scalar; \| \cdot \|_A represents A-norm. - - -## 3. Algorithmic Implementation - -**linear-conjugate-gradient-algorithm** -$$ -\begin{algorithmic} -\State $x_0 \leftarrow \text{Initial guess}, \quad r_0 = b - A x_0, \quad p_0 = r_0$ -\For{$k = 0, 1, 2, \dots \text{ until } \|r_k\|_2 < \text{tol}$} -\State $w_k = A p_k \quad \text{(single matrix-vector product)}$ -\State $\alpha_k \leftarrow \frac{r_k^T r_k}{p_k^T w_k}$ -\State $x_{k+1} \leftarrow x_k + \alpha_k p_k \quad \text{(AXPY update 1)}$ -\State $r_{k+1} \leftarrow r_k - \alpha_k w_k \quad \text{(AXPY update 2)}$ -\State $\beta_k \leftarrow \frac{r_{k+1}^T r_{k+1}}{r_k^T r_k}$ -\State $p_{k+1} \leftarrow r_{k+1} + \beta_k p_k \quad \text{(AXPY update 3)}$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf, Section 2.1, p. 242; IterMethBook_2ndEd.pdf.pdf, Section 6.1, p. 214_ - - -## 4. Known Pitfalls - -- **cg-indefinite-matrix-breakdown**: Standard Conjugate Gradient relies strictly on positive definiteness of coefficient matrix A (p_k^T A p_k > 0). If applied to indefinite, singular, or non-symmetric systems, denominator p_k^T A p_k can vanish or become negative, causing division by zero, loss of descent directions, or catastrophic divergence. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 6.1, p. 214; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 1, p. 3)_ -- **floating-point-orthogonality-loss**: In finite precision arithmetic, residual vectors r_k gradually lose mutual orthogonality as iteration counts increase. This leads to residual delay and iteration inflation, requiring reorthogonalization or preconditioning to maintain superlinear convergence. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 6.1, p. 214)_ - -## References - -- IterMethBook_2ndEd.pdf.pdf -- Schneider_2020_A dynamical view of nonlinear conjugate gradient methods with applications to.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-convergence-diagnostics.md b/packages/akms/src/akms/_bundled/global_nodes/solver-convergence-diagnostics.md deleted file mode 100644 index eaf3f8f..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-convergence-diagnostics.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -id: solver-convergence-diagnostics -title: Iterative Solver Convergence Diagnostics -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- diagnostics -- convergence -- residual -- condition-number -- eigenvalue -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-cg-algorithm - type: refines - weight: 0.7 -- to: solver-gmres-algorithm - type: refines - weight: 0.7 -- to: solver-pcg-algorithm - type: refines - weight: 0.7 -- to: solver-jfnk - type: refines - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Iterative Solver Convergence Diagnostics - -## Summary - -Convergence diagnostics for iterative linear and nonlinear solvers evaluate numerical progress, residual reduction rates, and operator spectrums to ensure solution accuracy in computational mechanics. Key diagnostic metrics include relative residual norms, absolute residual norms, solution update step sizes, inexact Newton forcing conditions, and Lanczos eigenvalue estimates used for polynomial preconditioner scaling. - -## 1. Core Concept - -Iterative linear solvers (such as Conjugate Gradient, GMRES, and BiCGSTAB) and nonlinear solvers (such as Newton-Raphson, JFNK, and L-BFGS) rely on robust convergence diagnostics to determine when solution iterates x_k have reached required engineering tolerances. In linear solvers, convergence is monitored by tracking the unpreconditioned relative residual norm ||r_k||_2 / ||r_0||_2 or absolute residual norm ||r_k||_2 against prescribed thresholds (e.g., 10^-10). In non-convex physical problems such as phase-field fracture, tracking energy functional values or solution increments alone is insufficient: total potential energy often reaches a flat numerical plateau during rapid crack propagation while residual norms remain unacceptably large (>10^-6), requiring strict dual-field residual and increment criteria. In inexact Newton-Krylov methods, forcing parameters \eta_k control inner linear solver convergence to prevent oversolving far from the root. Furthermore, Lanczos iterations are executed during preconditioner setup to estimate maximum eigenspectrum bounds \lambda_max(M^-1 A), ensuring optimal spectral scaling for Chebyshev polynomial smoothers. - -## 2. Mathematical Formulation - -**relative-residual-norm-criterion** -$$ -\frac{\|r_k\|_2}{\|r_0\|_2} \le \text{tol}_{\text{res}} \quad \text{or} \quad \|r_k\|_2 \le \text{tol}_{\text{abs}} -$$ -_Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.1, p. 11; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.1, p. 360_ - -**inexact-newton-forcing-condition** -$$ -\|J(u_k) du_k + F(u_k)\|_2 \le \eta_k \|F(u_k)\|_2 -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3.2, p. 363_ - -**coupled-field-residual-and-increment-diagnostics** -$$ -\frac{\|r_u^{(k)}\|_2}{\|r_u^{(0)}\|_2} \le \text{TOL}_{\text{Res}}, \quad \frac{\|\Delta u^{(k)}\|_2}{\|\Delta u^{(0)}\|_2} \le \text{TOL}_{\text{Inc}} -$$ -_Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 3.2, p. 12; Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf, Section 3.2.1, p. 8_ - -**lanczos-eigenvalue-estimator** -$$ -\lambda_{\max}(M^{-1} A) \approx \max_i \lambda_i(T_m) -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 10_ - -**Notation:** -r_k represents unpreconditioned linear residual vector; F(u_k) represents nonlinear residual vector; J(u_k) represents Jacobian operator matrix; du_k, \Delta u_k represent solution update vectors; \eta_k represents inexact Newton forcing term parameter; T_m represents tridiagonal Lanczos matrix; \lambda_max represents maximum eigenvalue estimate. - - -## 3. Algorithmic Implementation - -**inexact-newton-krylov-stopping-monitor** -$$ -\begin{algorithmic} -\State $\text{Evaluate outer nonlinear residual } F(u_k) \text{ and check relative stopping criterion } \|F(u_k)\|_2 / \|F(u_0)\|_2 < \text{tol}_{\text{res}}$ -\State $\text{Set inner Krylov forcing parameter } \eta_k \in (0, 1) \text{ to prevent oversolving}$ -\State $\text{Execute Krylov linear solver iterations until inner residual satisfies } \|J(u_k) du_k + F(u_k)\|_2 \le \eta_k \|F(u_k)\|_2$ -\State $\text{Compute update step } du_k \text{ and check solution update norm } \|du_k\|_2 / \|u_k\|_2 < \text{tol}_{\text{update}}$ -\State $u_{k+1} = u_k + s_k du_k$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.1, p. 360; Section 2.3.2, p. 364_ - -**lanczos-preconditioner-eigenspectrum-estimator** -$$ -\begin{algorithmic} -\State $\text{Initialize normalized seed vector } v_1 \text{ with } \|v_1\|_2 = 1, \text{ set } v_0 = 0, \beta_0 = 0$ -\For{$j = 1 \text{ to } m \quad \text{(typically } m = 10 \text{ iterations during setup)}$} -\State $w_j = M^{-1} A v_j \quad \text{(apply preconditioned operator on seed vector)}$ -\State $\alpha_j = v_j^T w_j$ -\State $w_j \leftarrow w_j - \alpha_j v_j - \beta_{j-1} v_{j-1}$ -\State $\beta_j = \|w_j\|_2$ -\State $v_{j+1} = w_j / \beta_j$ -\EndFor -\State $\text{Form } m \times m \text{ tridiagonal matrix } T_m \text{ with diagonal } \alpha_j \text{ and subdiagonals } \beta_j$ -\State $\text{Compute maximum eigenvalue } \lambda_{\max} = \max_i \lambda_i(T_m) \text{ to set Chebyshev polynomial bounds } [0.1 \lambda_{\max}, 1.1 \lambda_{\max}]$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section III.A, p. 3; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 10_ - - -## 4. Known Pitfalls - -- **premature-termination-on-energy-plateau**: In non-convex mechanical problems like phase-field brittle fracture, the total potential energy functional E(u, d) reaches a flat numerical plateau during rapid crack propagation while absolute residual norms ||r_u||_2 and ||r_d||_2 remain unacceptably large (>10^-6). Terminating iterations based on energy flattening or solution increments under-predicts crack growth; strict residual-based stopping criteria are mandatory. _(Source: Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf, Section 4.1, pp. 13-14)_ -- **oversolving-far-from-root-linearization**: Solving inner Krylov linear systems to an overly tight relative tolerance (\eta_k << 1) when the outer Newton iterate u_k is far from the true root wastes linear solver iterations on an inaccurate linearization. Adaptive forcing terms \eta_k balance inner and outer convergence. _(Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3.2, p. 364)_ -- **recursive-vs-true-residual-drift**: In short-recurrence Krylov solvers (such as DQGMRES, BiCGSTAB, or restarted GMRES), the residual vector updated recursively in finite-precision arithmetic diverges from the true residual b - A x_k. Periodically evaluating the explicit residual b - A x_k prevents false convergence reporting. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 6.11, p. 182; Section 7.4.2, p. 247)_ - -## References - -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- Jin et al. - A novel phase-field monolithic scheme for brittle crack propagation based on the limited-memory BFGS.pdf -- Ramos et al. - 2025 - Phase-field fracture analysis A gradient-based line search strategy for the L-BFGS algorithm.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf -- IterMethBook_2ndEd.pdf.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-direct.md b/packages/akms/src/akms/_bundled/global_nodes/solver-direct.md deleted file mode 100644 index e31bcc9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-direct.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: solver-direct -title: Direct Sparse Solvers (LU, Cholesky, LDLT) -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- direct -- lu -- cholesky -- sparse -- fill-in -- metis -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-cg-algorithm - type: contradicts - weight: 0.0 -- to: solver-gmres-algorithm - type: contradicts - weight: 0.0 -- to: precond-ichol-ilu - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Direct Sparse Solvers (LU, Cholesky, LDLT) - -## Summary - -Direct sparse solvers compute exact solutions x = A^-1 b for discretized linear algebraic equations in computational mechanics through matrix factorizations such as LU, Cholesky (L L^T), and L D U decomposition. Operating through a structured four-phase pipeline—preordering, symbolic factorization, numerical factorization, and triangular solve sweeps—direct solvers eliminate iteration-count uncertainty, but incur substantial memory and computational overhead due to fill-in nonzeros generated during elimination. - -## 1. Core Concept - -Direct sparse solvers compute exact solutions to linear systems Ax = b arising from finite element discretizations without relying on iterative convergence criteria or preconditioning operators. For symmetric positive-definite (SPD) stiffness matrices, Cholesky factorization factors A into lower triangular matrix L such that A = L L^T; for general unsymmetric or indefinite systems, LU or L D U factorizations decompose A = L U or A = L D U. A standard sparse direct solver operates in four distinct phases: (1) Preordering, where fill-reducing graph permutations (such as minimum degree or nested dissection ordering) reorder matrix rows and columns to minimize bandwidth and fill-in; (2) Symbolic Factorization, which sets up the sparsity pattern NZ(L + U) of the factored matrices without numerical floating-point operations; (3) Numerical Factorization, where actual numerical entries of L and U are computed; and (4) Triangular Solve Sweeps, where forward substitution L y = P b and backward substitution U z = y produce the final solution x = P^T z. While direct solvers excel as coarse-grid exact sub-solvers in multigrid hierarchies or for systems with multiple right-hand sides, factorization fill-in (creation of new nonzeros in L and U) generates heavy memory and arithmetic overhead for large 3D discretizations. - -## 2. Mathematical Formulation - -**sparse-direct-lu-factorization** -$$ -A = L U \quad \text{or} \quad A = L D U -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 3.6, p. 96_ - -**cholesky-factorization** -$$ -A = L L^T -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 3.6, p. 96_ - -**triangular-solve-sweeps** -$$ -L y = P b, \quad U z = y, \quad x = Q z -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 3.6, p. 96_ - -**Notation:** -A represents global sparse stiffness matrix; L, U represent lower and upper triangular factor matrices; D represents diagonal matrix; P, Q represent fill-reducing permutation matrices; b represents load vector; x represents primal solution vector; NZ(A) represents nonzero pattern of A. - - -## 3. Algorithmic Implementation - -**sparse-direct-solver-four-phase-pipeline** -$$ -\begin{algorithmic} -\State $\text{Phase 1 (Preordering): Compute fill-reducing permutation matrix } P \text{ via minimum degree or nested dissection ordering}$ -\State $\text{Phase 2 (Symbolic Factorization): Determine nonzero pattern } \text{NZ}(L + U) \text{ purely from graph connectivity without numerical values}$ -\State $\text{Phase 3 (Numerical Factorization): Compute numerical entries of factors } L \text{ and } U \text{ such that } P A P^T = L U \text{ (or } L L^T\text{)}$ -\State $\text{Phase 4 (Triangular Sweeps): Solve } L y = P b \text{ via forward substitution sweep, solve } U z = y \text{ via backward substitution sweep, and set } x = P^T z$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: IterMethBook_2ndEd.pdf.pdf, Section 3.6, p. 96_ - -**rcm-reordering-algorithm** -$$ -\begin{algorithmic} -\State $\text{Identify pseudo-peripheral initial node } v \text{ with minimal degree in adjacency graph}$ -\State $\text{Traverse graph level sets via Breadth-First Search (BFS), ordering adjacent nodes by increasing degree}$ -\State $\text{Reverse generated node permutation list } \pi \text{ to form Reverse Cuthill-McKee (RCM) ordering}$ -\State $\text{Construct reordered bandwidth-reduced system matrix } A_{\text{RCM}} = P_{\text{RCM}} A P_{\text{RCM}}^T$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: IterMethBook_2ndEd.pdf.pdf, Section 3.3.3, p. 84, Algorithm 3.1_ - - -## 4. Known Pitfalls - -- **sparse-direct-fill-in-memory-explosion**: During numerical elimination (LU or Cholesky factorization), arithmetic updates generate new nonzeros (fill-in) in matrix entries that were zero in original matrix A. For large 3D finite element discretizations, fill-in dramatically increases memory requirements and floating-point operation counts, causing out-of-memory solver failure on fine meshes. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 3.6, p. 96; Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Section I, p. 1)_ -- **triangular-solve-sequential-bottleneck**: Forward and backward triangular solves (L y = b and U x = y) require row-by-row recursive data dependencies that create severe sequential bottlenecks on parallel CPU and GPU architectures, limiting parallel speedup compared to matrix-vector multiplications in Krylov solvers. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 10.3, p. 301; Section 12.1, p. 376)_ - -## References - -- IterMethBook_2ndEd.pdf.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-explicit-dynamics.md b/packages/akms/src/akms/_bundled/global_nodes/solver-explicit-dynamics.md deleted file mode 100644 index 05e6260..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-explicit-dynamics.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: solver-explicit-dynamics -title: 'Explicit Dynamics: Central Difference & CFL' -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- explicit-dynamics -- central-difference -- CFL -- lumped-mass -- mass-scaling -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-newmark-hht - type: contradicts - weight: 0.0 -- to: solver-imex-splitting - type: feeds-into - weight: 0.5 -- to: solver-gpu-data-layout - type: requires - weight: 1.0 -- to: pf-dynamic-brittle - type: feeds-into - weight: 0.5 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Explicit Dynamics: Central Difference & CFL - -## Summary - -Explicit time integration schemes, such as the central difference method, solve transient elastodynamic equations without assembling or factorizing global stiffness matrices. By pairing explicit time stepping with diagonal lumped mass matrices, explicit dynamics computes nodal accelerations and displacements via element-local vector updates. Numerical stability is conditionally governed by the Courant-Friedrichs-Lewy (CFL) condition, which bounds the time step size by the maximum eigenfrequency of the system. Mass scaling techniques selectively modify the mass operator to artificially depress high-frequency modes and enlarge critical time steps. - -## 1. Core Concept - -Explicit time integration for structural dynamics solves the discretized system of ordinary differential equations M \ddot{u} + C \dot{u} + K u = f^{\text{ext}}. By utilizing a diagonal lumped mass matrix M, the acceleration vector \ddot{u}_n = M^{-1} (f_n^{\text{ext}} - f_n^{\text{int}}) is computed directly via element-wise vector scaling without matrix inversions or tangent stiffness linearizations. In the explicit central difference scheme, displacement iterates u_{n+1} and velocity updates \dot{u}_{n+1/2} are updated via short time step increments \Delta t. The method is conditionally stable, requiring step sizes to satisfy the Courant-Friedrichs-Lewy (CFL) limit \Delta t \le \Delta t_{\text{crit}} = 2 / \omega_{\max}, where \omega_{\max} is the highest natural frequency of the element assembly. To overcome severe CFL time step constraints in fine-mesh regions, mass scaling strategies add semi-definite mass terms E_e = \beta m_e (I - u u^T) to local element mass matrices, depressing high-frequency eigenvalues while preserving linear momentum and rigid-body translations. - -## 2. Mathematical Formulation - -**central-difference-acceleration-update** -$$ -\ddot{u}_n = M^{-1} (f_n^{\text{ext}} - f_n^{\text{int}}) -$$ -_Source: Mass_Scaling.pdf, Section 1, p. 469_ - -**cfl-critical-time-step-condition** -$$ -\Delta t \le \Delta t_{\text{crit}} = \frac{2}{\omega_{\max}} -$$ -_Source: Mass_Scaling.pdf, Section 1, p. 470_ - -**selective-mass-scaling-element-matrix** -$$ -\bar{M}_e = M_e + E_e, \quad E_e = \beta m_e (I_8 - u u^T) -$$ -_Source: Mass_Scaling.pdf, Section 2.2.1, p. 476_ - -**Notation:** -u represents nodal displacement vector; \dot{u}, \ddot{u} represent nodal velocity and acceleration vectors; M represents diagonal lumped mass matrix; K represents stiffness matrix; f^{\text{ext}}, f^{\text{int}} represent external and internal force vectors; \Delta t represents time step size; \omega_{\max} represents maximum system eigenfrequency; E_e represents mass scaling operator matrix. - - -## 3. Algorithmic Implementation - -**central-difference-explicit-dynamics-loop** -$$ -\begin{algorithmic} -\State $\text{Initialize } u_0, \dot{u}_0, \text{ diagonal lumped mass matrix } M, \text{ and critical step } \Delta t \le 2 / \omega_{\max}$ -\State $\ddot{u}_0 = M^{-1} (f_0^{\text{ext}} - f^{\text{int}}(u_0))$ -\For{$n = 0, 1, 2, \dots \text{ until } t_n \ge t_{\text{final}}$} -\State $\dot{u}_{n+1/2} = \dot{u}_{n-1/2} + \Delta t \, \ddot{u}_n$ -\State $u_{n+1} = u_n + \Delta t \, \dot{u}_{n+1/2}$ -\State $f_{n+1}^{\text{int}} = \text{EvaluateInternalForces}(u_{n+1}) \quad \text{(element-level matrix-free evaluation)}$ -\State $\ddot{u}_{n+1} = M^{-1} (f_{n+1}^{\text{ext}} - f_{n+1}^{\text{int}}) \quad \text{(direct element-wise division)}$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Mass_Scaling.pdf, Section 1, pp. 469-470; Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 2, p. 59_ - - -## 4. Known Pitfalls - -- **cfl-time-step-instability**: Exceeding the critical CFL time step \Delta t > 2 / \omega_{\max} causes unbounded numerical energy growth and immediate instability in explicit central difference time integration. _(Source: Mass_Scaling.pdf, Section 1, p. 470)_ -- **excessive-mass-scaling-frequency-distortion**: Applying overly aggressive mass scaling parameter \beta \to \infty artificially depresses physical natural frequencies, altering transient wave speeds and dynamic structural response. _(Source: Mass_Scaling.pdf, Section 2.2.1, p. 476; Section 2.2.3, p. 487)_ - -## References - -- Mass_Scaling.pdf -- Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf -- Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-gmres-algorithm.md b/packages/akms/src/akms/_bundled/global_nodes/solver-gmres-algorithm.md deleted file mode 100644 index 8cf459b..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-gmres-algorithm.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -id: solver-gmres-algorithm -title: GMRES & Restarted GMRES -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- GMRES -- krylov -- arnoldi -- non-symmetric -- restart -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-cg-algorithm - type: refines - weight: 0.7 -- to: solver-bicgstab-algorithm - type: contradicts - weight: 0.0 -- to: precond-jacobi-block-jacobi - type: requires - weight: 1.0 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# GMRES & Restarted GMRES - -## Summary - -The Generalized Minimal Residual (GMRES) method is a Krylov subspace iterative algorithm developed by Saad and Schultz for solving general non-symmetric and indefinite linear systems Ax = b. By constructing an orthonormal Arnoldi basis V_m via Modified Gram-Schmidt or Householder transformations, GMRES computes solution updates x_m = x_0 + V_m y_m that explicitly minimize the Euclidean norm of the residual vector ||b - A x_m||_2 over the Krylov subspace. To manage memory and computational growth as iteration counts increase, restarted GMRES(m) periodically restarts Arnoldi basis generation. - -## 1. Core Concept - -GMRES minimizes the residual norm over the m-th Krylov subspace K_m(A, r_0) = \text{span}\{r_0, A r_0, \dots, A^{m-1} r_0\} for general non-symmetric linear systems arising in computational mechanics and Jacobian-Free Newton-Krylov (JFNK) formulations. Using the Arnoldi process, GMRES factorizes A V_m = V_{m+1} \bar{H}_m, where V_{m+1} contains orthonormal basis vectors and \bar{H}_m \in \mathbb{R}^{(m+1) \times m} is an upper Hessenberg matrix. The residual minimization problem ||b - A (x_0 + V_m y)||_2 transforms into a small (m+1) \times m least-squares problem ||\beta e_1 - \bar{H}_m y||_2, solved efficiently using Givens plane rotations without constructing intermediate solution vectors. In restarted GMRES(m), the iteration restarts every m steps using the current iterate as the new initial guess x_0, bounding memory storage at m vectors at the expense of potential convergence stagnation. - -## 2. Mathematical Formulation - -**gmres-least-squares-minimization** -$$ -y_m = \arg\min_{y \in \mathbb{R}^m} \|\beta e_1 - \bar{H}_m y\|_2 -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.1, p. 172_ - -**arnoldi-operator-relation** -$$ -A V_m = V_{m+1} \bar{H}_m -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.1, p. 172; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.2, p. 360_ - -**givens-rotation-residual-norm** -$$ -\|b - A x_m\|_2 = |\gamma_{m+1}| -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.3, pp. 176-177_ - -**Notation:** -A represents global non-symmetric coefficient matrix; x_m represents solution vector at step m; r_0 represents initial residual vector b - A x_0; V_m represents matrix of orthonormal Arnoldi vectors; \bar{H}_m represents upper Hessenberg matrix; Q_m represents sequence of Givens rotation matrices; \beta represents initial residual Euclidean norm. - - -## 3. Algorithmic Implementation - -**basic-gmres-algorithm** -$$ -\begin{algorithmic} -\State $r_0 = b - A x_0, \quad \beta = \|r_0\|_2, \quad v_1 = r_0 / \beta$ -\For{$j = 1 \text{ to } m$} -\State $w_j = A v_j \quad \text{(or matrix-free directional derivative } [F(u + \epsilon v_j) - F(u)] / \epsilon\text{)}$ -\For{$i = 1 \text{ to } j$} -\State $h_{i,j} = (w_j, v_i), \quad w_j \leftarrow w_j - h_{i,j} v_i \quad \text{(Modified Gram-Schmidt)}$ -\EndFor -\State $h_{j+1,j} = \|w_j\|_2$ -\If{$h_{j+1,j} == 0$} -\State $m \leftarrow j \quad \text{and break}$ -\EndIf -\State $v_{j+1} = w_j / h_{j+1,j}$ -\EndFor -\State $\text{Form Hessenberg matrix } \bar{H}_m = \{h_{i,j}\}_{1 \le i \le m+1, 1 \le j \le m}$ -\State $\text{Compute } y_m = \arg\min_y \|\beta e_1 - \bar{H}_m y\|_2 \text{ using Givens rotations}$ -\State $x_m = x_0 + V_m y_m$ -\Return $x_m$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.1, p. 172, Algorithm 6.9; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.2, p. 361_ - -**restarted-gmres-algorithm** -$$ -\begin{algorithmic} -\State $\text{Initialize solution } x_0, \text{ restart parameter } m, \text{ and tolerance } \text{tol}$ -\While{$\|b - A x_0\|_2 \ge \text{tol}$} -\State $r_0 = b - A x_0, \quad \beta = \|r_0\|_2, \quad v_1 = r_0 / \beta$ -\State $\text{Generate Arnoldi basis } V_{m+1} \text{ and Hessenberg matrix } \bar{H}_m \text{ for } m \text{ steps}$ -\State $\text{Compute } y_m = \arg\min_y \|\beta e_1 - \bar{H}_m y\|_2 \text{ via Givens plane rotations}$ -\State $x_m = x_0 + V_m y_m$ -\State $x_0 \leftarrow x_m \quad \text{(restart with updated iterate)}$ -\EndWhile -\Return $x_0$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.5, p. 179, Algorithm 6.11; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.2, p. 361_ - - -## 4. Known Pitfalls - -- **gmres-restart-stagnation**: Restarted GMRES(m) can stagnate when the coefficient matrix A is indefinite or non-positive definite and restart parameter m is chosen too small to capture key eigenspectrum modes. Increasing restart size m or applying effective preconditioning eliminates stagnation. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.5, p. 179; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.2, p. 361)_ -- **modified-gram-schmidt-orthogonality-loss**: Generating Arnoldi basis vectors V_m using Modified Gram-Schmidt (MGS) in finite-precision arithmetic can suffer from loss of orthogonality when solving ill-conditioned systems. Utilizing Householder transformations or reorthogonalization maintains basis orthogonality. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.2, p. 173; Section 6.3.2, p. 162)_ - -## References - -- IterMethBook_2ndEd.pdf.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-gpu-data-layout.md b/packages/akms/src/akms/_bundled/global_nodes/solver-gpu-data-layout.md deleted file mode 100644 index ce24567..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-gpu-data-layout.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: solver-gpu-data-layout -title: GPU Data Layout & Performance Patterns -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- GPU -- data-layout -- SoA -- AoS -- coalescing -- atomics -- taichi -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-matrix-free-gpu - type: requires - weight: 1.0 -- to: precond-gpu-alternatives - type: feeds-into - weight: 0.5 -- to: precond-amg-gpu - type: refines - weight: 0.7 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# GPU Data Layout & Performance Patterns - -## Summary - -GPU data layout and memory access patterns determine performance in finite element simulations, as sparse matrix assembly and Krylov solver sweeps are memory-bandwidth bound. To maximize throughput on heterogeneous GPU hardware, finite element codes eliminate CPU-GPU data transfers using direct device memory array pointers (such as PETSc MatSeqAIJCUSPARSEGetArray), avoid thread branch divergence in sparse matrix assembly using precomputed lookup tables or split-phase COO formats (MatSetValuesCOO), and optimize memory coalescing through rowwise assembly algorithms or matrix-free tensor contractions. - -## 1. Core Concept - -Finite element calculations on GPUs—including local element assembly, sparse matrix insertion, and iterative linear solves—are fundamentally memory-bandwidth bound. Traditional assembly algorithms that perform binary searches on the CPU or within GPU threads suffer from severe branch divergence (up to 90%) and thread stalls. Replacing binary searches with precomputed lookup tables (nonzero_locations) or split-phase Coordinate (COO) interfaces eliminates branch divergence and enables coalesced memory access. Furthermore, performing matrix assembly rowwise rather than cellwise groups memory updates by degree of freedom, reducing atomic write contention and L2 cache writeback traffic by up to 4x. In high-order discretizations, matrix-free partial assembly (fusing element restriction, basis evaluations, and quadrature point tensors into single GPU device kernels) bypasses sparse matrix allocation entirely, achieving high memory throughput on NVIDIA and AMD GPUs. Frameworks like Taichi (MeshTaichi) and JAX-FEM provide compiler-level GPU acceleration for parallel mesh operations and automatic differentiation. - -## 2. Mathematical Formulation - -**gpu-matrix-free-bandwidth-model** -$$ -\text{Throughput} = \frac{\text{STREAM\_Bandwidth}}{\text{Bytes\_per\_DoF}} -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Section V.B, p. 5; Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3, p. 4_ - -**lookup-table-sparse-matrix-indexing** -$$ -r = \text{nonzero\_locations}[l] -$$ -_Source: Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.6, p. 5_ - -**atomic-global-matrix-assembly-update** -$$ -A[r] \leftarrow A[r] + A_e[j, k] -$$ -_Source: Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.5, p. 5_ - -**Notation:** -A represents global CSR sparse matrix values array on GPU device; A_e represents element stiffness/residual matrix; r represents destination CSR array offset; nonzero_locations represents precomputed lookup table array; STREAM_Bandwidth represents GPU memory bandwidth capacity. - - -## 3. Algorithmic Implementation - -**lookup-table-gpu-global-assembly** -$$ -\begin{algorithmic} -\State $\text{Precompute } \text{nonzero\_locations} \text{ lookup table mapping each element matrix entry } (j, k) \text{ to its global CSR array position } r$ -\State $\text{Launch GPU CUDA kernel } \text{cuda\_global\_assembly} \text{ with grid-stride thread loops}$ -\For{$i = \text{blockIdx.x} \times \text{blockDim.x} + \text{threadIdx.x} \text{ to } N_{\text{cells}} \text{ stride } \text{blockDim.x} \times \text{gridDim.x}$} -\State $\text{Compute element matrix } A_e \text{ via auto-generated } \text{tabulate\_tensor} \text{ in thread registers}$ -\For{$j = 0 \text{ to } n_e - 1, \quad k = 0 \text{ to } n_e - 1$} -\State $r = \text{nonzero\_locations}[i \times n_e^2 + j \times n_e + k]$ -\State $\text{atomicAdd}(\&A[r], A_e[j, k]) \quad \text{(direct device memory update without binary search)}$ -\EndFor -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.6, pp. 5-6, Algorithm 5_ - -**rowwise-gpu-matrix-assembly** -$$ -\begin{algorithmic} -\State $\text{Construct } \text{cells\_per\_dof} \text{ mapping to assign GPU threads rowwise to global matrix DOFs}$ -\State $\text{Launch CUDA kernel } \text{cuda\_rowwise\_assembly} \text{ using warp-coalesced thread access}$ -\For{$p = \text{blockIdx.x} \times \text{blockDim.x} + \text{threadIdx.x} \text{ to } \text{cells\_per\_dof\_ptr}[N_{\text{rows}}]$} -\State $\text{Compute element matrix } A_e \text{ and identify row match } j == \text{element\_matrix\_rows}[p]$ -\State $l = ((p / \text{warpSize}) \times 4 + k) \times \text{warpSize} + p \pmod{\text{warpSize}}$ -\State $r = \text{nonzero\_locations}[l]$ -\State $\text{atomicAdd}(\&A[r], A_e[j, k]) \quad \text{(coalesced write reducing L2 cache memory traffic by 4x)}$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.7, p. 6, Algorithm 6_ - - -## 4. Known Pitfalls - -- **cpu-gpu-data-transfer-latency-penalty**: Transferring global stiffness matrices or solution vectors between CPU host memory and GPU device memory after assembly increases solution time by 3x to 5x, completely negating GPU compute acceleration. Assembly and linear solves must remain entirely on the GPU, using direct device array pointers (such as PETSc MatSeqAIJCUSPARSEGetArray). _(Source: Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.3, p. 4; Section 4.4, p. 8, Fig. 1)_ -- **branch-divergence-in-binary-search**: Performing binary searches within GPU threads to locate column insertion points during sparse CSR matrix assembly causes severe thread branch divergence within warps (~90% divergence), stalling 95% of execution samples on memory dependencies. Replacing binary searches with a precomputed lookup table eliminates divergence and restores memory throughput. _(Source: Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.6, p. 5)_ -- **atomic-contention-in-global-assembly**: Uncoordinated atomic updates (atomicAdd) from multiple concurrent GPU threads writing to shared global matrix DOFs cause atomic write contention and irregular cache writes. Switching from cellwise to rowwise assembly improves write locality, reducing L2 cache writeback traffic from >2 GiB to ~500 MiB on NVIDIA V100 GPUs. _(Source: Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.7, p. 6; Section 4.2, p. 7)_ - -## References - -- Trotter et al_2023_Targeting performance and user-friendliness.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf -- Shen et al. - 2024 - Preconditioned Nonlinear Conjugate Gradient Method for Real-time Interior-point Hyperelasticity.pdf -- Xue et al_2023_JAX-FEM.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-imex-splitting.md b/packages/akms/src/akms/_bundled/global_nodes/solver-imex-splitting.md deleted file mode 100644 index fd1d52f..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-imex-splitting.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: solver-imex-splitting -title: IMEX Time Integration for Coupled Problems -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- IMEX -- ARK -- time-integration -- splitting -- hughes-1978 -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-explicit-dynamics - type: refines - weight: 0.7 -- to: solver-newmark-hht - type: refines - weight: 0.7 -- to: pf-explicit-time-integration - type: feeds-into - weight: 0.5 -- to: solver-jfnk - type: feeds-into - weight: 0.5 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# IMEX Time Integration for Coupled Problems - -## Summary - -Implicit-explicit (IMEX) time integration schemes partition computational domains or discretized governing equations into implicit and explicit element groups. Originated by Hughes and Liu (1978) for structural dynamics and transient wave propagation, IMEX methods apply implicit Newmark integration to stiff or complex structural regions while using explicit time stepping with diagonal mass matrices on remaining domains, balancing numerical stability with computational efficiency. - -## 1. Core Concept - -Transient finite element analysis often involves heterogeneous mesh regions where stiff elements or complex material models require small time steps if integrated explicitly, whereas large unstructured mesh domains are efficiently solved explicitly without global linear matrix factorizations. Implicit-explicit (IMEX) formulations partition the mesh arrays into implicit (I) and explicit (E) element groups, splitting global mass, damping, stiffness, and internal force vectors into M = M^I + M^E, C = C^I + C^E, K = K^I + K^E, and F = F^I + F^E. The explicit group utilizes a diagonal mass matrix M^E and predictor-corrector time stepping, while the implicit group forms an effective stiffness matrix (K^*)^I = \frac{1}{\beta \Delta t^2} M^I + \frac{\gamma}{\beta \Delta t} C^I + K^I. Coupling implicit and explicit groups produces an effective global stiffness K^* = (K^*)^I + (K^*)^E where explicit element contributions reduce to diagonal mass scaling \frac{1}{\beta \Delta t^2} M^E, dramatically reducing global matrix profile size while restricting the Courant stability limit solely to explicit mesh elements. - -## 2. Mathematical Formulation - -**imex-array-partitioning** -$$ -M = M^I + M^E, \quad C = C^I + C^E, \quad K = K^I + K^E, \quad F = F^I + F^E -$$ -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 1, p. 375, Eqs. 13-15_ - -**imex-effective-stiffness-matrix** -$$ -K^* = (K^*)^I + (K^*)^E \quad \text{where } (K^*)^I = \frac{1}{\beta \Delta t^2} M^I + \frac{\gamma}{\beta \Delta t} C^I + K^I, \quad (K^*)^E = \frac{1}{\beta \Delta t^2} M^E -$$ -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 2, p. 376, Eqs. 21-23_ - -**imex-effective-force-vector** -$$ -F_{n+1}^* = (F_{n+1}^*)^I + (F_{n+1}^*)^E -$$ -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 2, p. 376, Eqs. 24-26_ - -**imex-explicit-group-courant-stability** -$$ -\Omega = \omega \Delta t \le \frac{(\xi^2 + 2\gamma)^{1/2} - \xi}{\gamma} -$$ -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 1, p. 376, Eq. 18_ - -**Notation:** -M, C, K represent global mass, damping, and stiffness matrices; M^I, C^I, K^I represent implicit element group matrices; M^E, C^E, K^E represent explicit element group matrices; d_n, v_n, a_n represent nodal displacement, velocity, and acceleration vectors; \tilde{d}_{n+1}, \tilde{v}_{n+1} represent predictor displacement and velocity vectors; \Delta t represents time step size; \gamma, \beta represent Newmark time integration parameters. - - -## 3. Algorithmic Implementation - -**hughes-liu-imex-transient-algorithm** -$$ -\begin{algorithmic} -\State $\text{Partition mesh elements into implicit group } I \text{ and explicit group } E \text{ with diagonal mass } M^E$ -\State $\text{Form effective stiffness } K^* = (K^*)^I + (K^*)^E \text{ where } (K^*)^I = \frac{1}{\beta \Delta t^2} M^I + \frac{\gamma}{\beta \Delta t} C^I + K^I \text{ and } (K^*)^E = \frac{1}{\beta \Delta t^2} M^E$ -\For{$n = 0, 1, 2, \dots \text{ until } t_n \ge t_{\text{final}}$} -\State $\tilde{d}_{n+1} = d_n + \Delta t v_n + \frac{\Delta t^2}{2} (1 - 2\beta) a_n \quad \text{(displacement predictor)}$ -\State $\tilde{v}_{n+1} = v_n + \Delta t (1 - \gamma) a_n \quad \text{(velocity predictor)}$ -\State $\text{Assemble effective force } F_{n+1}^* = (F_{n+1}^*)^I + (F_{n+1}^*)^E$ -\State $\text{Solve } K^* d_{n+1} = F_{n+1}^* \text{ for displacement } d_{n+1}$ -\State $a_{n+1} = \frac{1}{\beta \Delta t^2} (d_{n+1} - \tilde{d}_{n+1}) \quad \text{(acceleration corrector)}$ -\State $v_{n+1} = \tilde{v}_{n+1} + \gamma \Delta t a_{n+1} \quad \text{(velocity corrector)}$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 2, p. 376_ - - -## 4. Known Pitfalls - -- **explicit-element-group-courant-instability**: In IMEX time integration, while the implicit element group is unconditionally stable, the time step size \Delta t remains conditionally bounded by the highest natural frequency \omega_{\max} of the explicit element group E according to \omega \Delta t \le ((\xi^2 + 2\gamma)^{1/2} - \xi) / \gamma. Accidental inclusion of extremely stiff or refined elements in the explicit group causes catastrophic numerical instability. _(Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 1, p. 376)_ -- **nondiagonal-explicit-mass-matrix-breakdown**: The efficiency of explicit element evaluation in IMEX formulations requires the explicit mass matrix M^E to be strictly diagonal (lumped). Utilizing a consistent non-diagonal mass matrix in explicit element groups forces matrix inversions across explicit mesh domains, destroying the computational advantage of IMEX partitioning. _(Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 1, p. 375)_ - -## References - -- Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf -- Mass_Scaling.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-jfnk.md b/packages/akms/src/akms/_bundled/global_nodes/solver-jfnk.md deleted file mode 100644 index 8b5766e..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-jfnk.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -id: solver-jfnk -title: Jacobian-Free Newton-Krylov (JFNK) -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- JFNK -- newton-krylov -- jacobian-free -- eisenstat-walker -- knoll-keyes -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-gmres-algorithm - type: requires - weight: 1.0 -- to: solver-matrix-free-operator - type: refines - weight: 0.7 -- to: optim-newton-krylov - type: refines - weight: 0.7 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Jacobian-Free Newton-Krylov (JFNK) - -## Summary - -Jacobian-Free Newton-Krylov (JFNK) methods combine outer Newton-type nonlinear iterations with inner Krylov subspace linear iterative solvers (such as GMRES) to solve non-linear systems of algebraic equations F(u) = 0. The defining characteristic of JFNK is evaluating Jacobian-vector products J v directional derivatives matrix-free via finite difference residual evaluations without forming or storing the true Jacobian matrix. Preconditioning operator P is constructed separately using physics-based, lower-order, or lagged approximations to ensure rapid Krylov convergence. - -## 1. Core Concept - -Jacobian-Free Newton-Krylov (JFNK) is a multi-level nested iteration framework for solving systems of non-linear partial differential equations discretized as F(u) = 0. At outer Newton step k, the linearized correction equation J(u_k) du_k = -F(u_k) is solved using an inexact Newton criterion ||J(u_k) du_k + F(u_k)||_2 <= \eta_k ||F(u_k)||_2, where forcing parameter \eta_k controls linear convergence and prevents oversolving far from the root. Instead of assembling and storing full n x n Jacobian matrices J = \partial F / \partial u, Krylov solvers (e.g. GMRES) probe the Jacobian action exclusively through directional Fréchet finite-difference derivatives J v \approx (F(u + \epsilon v) - F(u)) / \epsilon. To achieve grid-independent Krylov convergence, right preconditioning J P^-1 (P v) is applied, where preconditioner P is formed from lagged Jacobians, lower-order discretizations, or physics-based operator splittings. - -## 2. Mathematical Formulation - -**inexact-newton-linear-system** -$$ -\|J(u_k) du_k + F(u_k)\|_2 \le \eta_k \|F(u_k)\|_2 -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.1, p. 360; Section 2.3.2, p. 363_ - -**matrix-free-jacobian-vector-product** -$$ -J v \approx \frac{F(u + \epsilon v) - F(u)}{\epsilon} -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.2, p. 362_ - -**perturbation-parameter-epsilon-selection** -$$ -\epsilon = \frac{\sqrt{\epsilon_{\text{mach}}}}{\|v\|_2} (1 + \|u\|_2) \quad \text{or} \quad \epsilon = \frac{1}{n \|v\|_2} \sum_{i=1}^n \sqrt{\epsilon_{\text{mach}}} (1 + |u_i|) -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.2, p. 362_ - -**right-preconditioned-jacobian-action** -$$ -J P^{-1} v \approx \frac{F(u + \epsilon y) - F(u)}{\epsilon} \quad \text{where } P y = v -$$ -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 3.1, p. 367_ - -**Notation:** -F(u) represents non-linear residual vector; u represents solution state vector; J represents Jacobian matrix operator; du represents Newton correction vector; v represents Krylov vector; \eta_k represents inexact Newton forcing parameter; \epsilon represents finite difference step size; P represents preconditioning operator matrix; \epsilon_{\text{mach}} represents floating point machine epsilon. - - -## 3. Algorithmic Implementation - -**jfnk-inexact-newton-outer-loop** -$$ -\begin{algorithmic} -\State $\text{Initialize solution guess } u_0, \text{ non-linear tolerance } \text{tol}_{\text{res}}, \text{ and maximum Newton steps } K_{\max}$ -\For{$k = 0, 1, 2, \dots, K_{\max}$} -\State $\text{Evaluate non-linear residual } F(u_k)$ -\If{$\|F(u_k)\|_2 / \|F(u_0)\|_2 < \text{tol}_{\text{res}}$} -\Return $u_k \quad \text{(converged solution)}$ -\EndIf -\State $\text{Select inexact Newton forcing term } \eta_k \in (0, 1)$ -\State $\text{Solve linear system } J(u_k) du_k = -F(u_k) \text{ using preconditioned GMRES to tolerance } \|J du_k + F\|_2 \le \eta_k \|F\|_2$ -\State $\text{Compute step size } \alpha_k \in (0, 1] \text{ via line search or trust region globalization}$ -\State $u_{k+1} = u_k + \alpha_k du_k$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.1, p. 360; Section 2.3.2, p. 363_ - -**right-preconditioned-jvp-evaluation** -$$ -\begin{algorithmic} -\State $\text{Given current solution } u, \text{ unpreconditioned residual } F(u), \text{ and Krylov vector } v$ -\State $\text{Solve preconditioner subproblem } P y = v \text{ for vector } y \text{ (e.g. via incomplete LU, AMG V-cycle, or physics split)}$ -\State $\text{Compute perturbation parameter } \epsilon = \frac{\sqrt{\epsilon_{\text{mach}}}}{\|y\|_2} (1 + \|u\|_2)$ -\State $\text{Evaluate perturbed residual } F(u + \epsilon y)$ -\State $\text{Compute matrix-vector product } w = \frac{F(u + \epsilon y) - F(u)}{\epsilon}$ -\Return $w \quad \text{(action of preconditioned Jacobian } J P^{-1} v\text{)}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.2, p. 362; Section 3.1, p. 367_ - - -## 4. Known Pitfalls - -- **finite-difference-perturbation-epsilon-imbalance**: In finite difference Jacobian-vector product evaluations J v \approx (F(u + \epsilon v) - F(u)) / \epsilon, choosing \epsilon too small causes subtractive cancellation and floating-point roundoff error domination, whereas choosing \epsilon too large introduces severe truncation error from higher-order non-linear terms. Balancing \epsilon using scaling formula \epsilon = \frac{\sqrt{\epsilon_{\text{mach}}}}{\|v\|_2} (1 + \|u\|_2) is required. _(Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.2, p. 362)_ -- **oversolving-inexact-newton-linear-iterations**: Solving linear Newton correction equations J(u_k) du_k = -F(u_k) to an unnecessarily tight relative tolerance (\eta_k \ll 1) when the outer iterate u_k is far from the true solution root wastes Krylov iterations and residual evaluations on an inaccurate local Taylor linearization. Utilizing adaptive forcing terms \eta_k balances inner Krylov and outer Newton convergence. _(Source: Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 2.3.2, p. 364)_ - -## References - -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- IterMethBook_2ndEd.pdf.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf -- Xue et al_2023_JAX-FEM.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-matrix-free-gpu.md b/packages/akms/src/akms/_bundled/global_nodes/solver-matrix-free-gpu.md deleted file mode 100644 index 708bd1d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-matrix-free-gpu.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: solver-matrix-free-gpu -title: 'Matrix-Free on GPU: Data Layout & Kernel Patterns' -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- matrix-free -- GPU -- taichi -- FEniCS -- shared-memory -- occupancy -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-matrix-free-operator - type: refines - weight: 0.7 -- to: solver-gpu-data-layout - type: requires - weight: 1.0 -- to: precond-gpu-alternatives - type: feeds-into - weight: 0.5 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Matrix-Free on GPU: Data Layout & Kernel Patterns - -## Summary - -Matrix-free operator evaluation on GPUs circumvents sparse matrix assembly and storage bottlenecks by evaluating element integrals on-the-fly via quadrature-point tensor contractions. In high-order finite element discretizations, matrix-free partial assembly reduces memory streaming footprint from ~750 bytes/DoF (for assembled CSR sparse matrices) down to ~140 bytes/DoF (for Q2 elements), overcoming the <2% peak FLOPS memory bandwidth saturation typical of assembled sparse matrix-vector products (SpMV). Modern libraries like libCEED and PETSc leverage JIT compilation (via NVRTC or hipRTC) to inline quadrature-point constitutive models into fused CUDA/HIP device kernels, maximizing parallel execution throughput on modern GPU hardware. - -## 1. Core Concept - -Finite element solvers relying on assembled compressed sparse row (CSR) matrices are strictly memory-bandwidth bound on modern GPU hardware. Storing double-precision matrix entries and integer column indices yields an arithmetic intensity of roughly 1 FLOP per 6 bytes, causing iterative Krylov solvers to saturate memory bandwidth at less than 2% of a GPU's peak floating-point performance. Matrix-free partial assembly restructures linear operator evaluation into a sequence of dense, localized tensor operations: global-to-local restriction (\mathcal{P}), element restriction (\mathcal{E}), basis evaluation at quadrature points (B), diagonal/block constitutive evaluation at quadrature points (D), and their transposed operations. By evaluating basis gradients and material constitutive laws on-the-fly at quadrature points, matrix-free representations reduce memory bandwidth demand by 5x or more compared to assembled SpMV. To eliminate overheads on modern architectures (NVIDIA V100/A100, AMD MI250X), runtime kernel generation (via NVRTC/hipRTC) inlines user-defined material constitutive functions (or automatic differentiation derivatives from tools like Enzyme) directly into CUDA/HIP device functions. Loop bounds and memory strides become compile-time constants, optimizing thread register allocation. - -## 2. Mathematical Formulation - -**matrix-free-operator-decomposition** -$$ -A = \mathcal{P}^T \mathcal{E}^T B^T D \mathcal{E} \mathcal{P} -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section II.C, p. 2, Fig. 1_ - -**arithmetic-intensity-and-memory-footprint** -$$ -\text{Memory Footprint}_{\text{MF}} \approx 140 \text{ B/DoF} \ll \text{Memory Footprint}_{\text{CSR}} \approx 750 \text{ B/DoF} -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section V.B, p. 5_ - -**Notation:** -A represents global matrix-free operator; \mathcal{P} represents global scatter/gather restriction operator; \mathcal{E} represents element restriction operator; B represents basis evaluation matrix at quadrature points; D represents quadrature point constitutive tensor matrix; v_T, v_L, v_E, q represent global, local, element, and quadrature point field vectors. - - -## 3. Algorithmic Implementation - -**matrix-free-quadrature-operator-apply** -$$ -\begin{algorithmic} -\State $v_L = \mathcal{P} v_T \quad \text{(gather global T-vector degrees of freedom to local sub-domain L-vector)}$ -\State $v_E = \mathcal{E} v_L \quad \text{(extract element-level E-vector DOFs)}$ -\State $q = B v_E \quad \text{(evaluate gradients/fields at element quadrature points Q-vector via tensor contractions)}$ -\State $q' = D q \quad \text{(apply material constitutive tangent transformation at quadrature points)}$ -\State $w_E = B^T q' \quad \text{(apply transposed basis gradients at quadrature points)}$ -\State $w_L = \mathcal{E}^T w_E \quad \text{(accumulate element contributions into local sub-domain vector)}$ -\State $w_T = \mathcal{P}^T w_L \quad \text{(scatter and sum local contributions into global T-vector)}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section II.C, p. 2, Fig. 1; Section V.B, p. 5_ - - -## 4. Known Pitfalls - -- **high-order-element-register-spilling-occupancy-drop**: Evaluating high-order finite elements (such as Q3 or higher) on GPUs in matrix-free kernels requires storing large basis transformation matrices and intermediate quadrature arrays in thread registers. High register consumption per thread causes register spilling to local GPU memory and reduces thread block occupancy, increasing latency on smaller problem sizes. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section II.C, p. 3; Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 4.5, p. 8)_ -- **assembled-spmv-memory-bandwidth-saturation**: Iterative solvers relying on assembled sparse CSR matrix-vector products (SpMV) require streaming 12-16 bytes per nonzero (double precision value plus integer column index), yielding an arithmetic intensity of ~1 FLOP per 6 bytes. On GPU architectures with >10 FLOPs/byte streaming capacity, SpMV saturates memory bandwidth at less than 2% of peak FLOPS performance. Matrix-free partial assembly bypasses sparse matrix streaming, achieving up to 6x higher throughput. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section I, p. 1; Section V.B, p. 5)_ -- **cpu-gpu-latency-synchronization-penalty**: Unnecessary host-device synchronization or CPU-GPU memory transfers during linear solver iterations or residual evaluations introduces severe latency penalties that dominate small-to-medium problem sizes, degrading parallel efficiency unless all operator evaluations and solver sweeps reside entirely in GPU device memory. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section V.A, p. 5; Trotter et al_2023_Targeting performance and user-friendliness.pdf, Section 3.3, p. 4)_ - -## References - -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf -- Trotter et al_2023_Targeting performance and user-friendliness.pdf -- Xue et al_2023_JAX-FEM.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-matrix-free-operator.md b/packages/akms/src/akms/_bundled/global_nodes/solver-matrix-free-operator.md deleted file mode 100644 index 07280aa..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-matrix-free-operator.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -id: solver-matrix-free-operator -title: Matrix-Free Operator Evaluation (libCEED Pattern) -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- matrix-free -- libCEED -- sum-factorization -- high-order -- FE -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-matrix-free-gpu - type: refines - weight: 0.7 -- to: solver-pcg-algorithm - type: feeds-into - weight: 0.5 -- to: precond-geometric-mg - type: feeds-into - weight: 0.5 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Matrix-Free Operator Evaluation (libCEED Pattern) - -## Summary - -Matrix-free operator evaluation represents finite element linear operators through partial assembly, evaluating stiffness and residual actions on-the-fly without assembling or storing global sparse matrices. Following the libCEED decomposition A = \mathcal{P}^T \mathcal{E}^T B^T D \mathcal{E} \mathcal{P}, operator evaluations compose global restriction (\mathcal{P}), element restriction (\mathcal{E}), basis evaluation (B), and quadrature-point constitutive tensor transformations (D). By bypassing assembled CSR matrix storage, matrix-free methods drastically reduce memory bandwidth demands and enable high throughput on CPU and GPU architectures. - -## 1. Core Concept - -Traditional finite element solvers rely on assembled sparse matrices (e.g. CSR format). For high-order discretizations (Q_p elements with p >= 2), storing sparse tangent matrices requires streaming O(p^{2d}) nonzeros per row, causing memory bandwidth saturation at less than 2% of peak GPU floating-point capacity. Matrix-free operator evaluation avoids sparse matrix allocation by factoring operator application into modular tensor operations. In the libCEED abstraction, a global vector (T-vector) is mapped to sub-domain local representations (L-vectors) via scatter/gather restriction operator \mathcal{P}, localized into element representations (E-vectors) via element restriction \mathcal{E}, evaluated at quadrature points (Q-vectors) via basis transform B, transformed by material constitutive laws via D, and accumulated back via transpose operations. For Q2 hexahedral elements, matrix-free partial assembly streams ~140 B/DoF compared to ~750 B/DoF for assembled CSR matrices (with 63 nonzeros per row). Furthermore, matrix-free data structures provide up to 2x efficiency gains even for linear (Q1) elements. - -## 2. Mathematical Formulation - -**libceed-operator-decomposition** -$$ -A = \mathcal{P}^T \mathcal{E}^T B^T D \mathcal{E} \mathcal{P} -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section II.C, p. 2, Fig. 1_ - -**libceed-jacobian-action** -$$ -J du = \sum_e (\mathcal{E}^e)^T [B_I, B_\xi]^T W^e \Lambda \begin{bmatrix} \hat{f}_{0,0} & \hat{f}_{0,1} \\ \hat{f}_{1,0} & \hat{f}_{1,1} \end{bmatrix} \begin{bmatrix} B_I \\ B_\xi \end{bmatrix} \mathcal{E}^e du -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section II.B, p. 2, Eq. 11_ - -**matrix-free-memory-footprint-reduction** -$$ -\text{Memory Footprint}_{\text{MF, } Q_2} \approx 140 \text{ B/DoF} \ll \text{Memory Footprint}_{\text{CSR, } Q_2} \approx 750 \text{ B/DoF} -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section V.B, p. 5_ - -**Notation:** -A represents global matrix-free operator; \mathcal{P} represents global scatter/gather restriction operator; \mathcal{E} represents element restriction operator; B represents basis evaluation matrix at quadrature points; D represents quadrature-point constitutive tensor matrix; J represents Jacobian operator; \hat{f}_{i,j} represent constitutive functional derivatives. - - -## 3. Algorithmic Implementation - -**libceed-matrix-free-operator-apply** -$$ -\begin{algorithmic} -\State $v_L = \mathcal{P} v_T \quad \text{(gather global T-vector DOFs to sub-domain local L-vector)}$ -\State $v_E = \mathcal{E} v_L \quad \text{(extract element DOFs into E-vector)}$ -\State $q = B v_E \quad \text{(evaluate fields and gradients at quadrature points Q-vector)}$ -\State $q' = D q \quad \text{(apply material constitutive tangent transformation at quadrature points)}$ -\State $w_E = B^T q' \quad \text{(apply transposed basis evaluation at quadrature points)}$ -\State $w_L = \mathcal{E}^T w_E \quad \text{(assemble element contributions into local sub-domain vector)}$ -\State $w_T = \mathcal{P}^T w_L \quad \text{(scatter/sum local updates into global T-vector)}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section II.C, p. 2, Fig. 1_ - - -## 4. Known Pitfalls - -- **assembled-matrix-storage-memory-bottleneck**: Assembling and storing sparse CSR matrices for high-order finite elements (Q_p for p >= 2) generates dense row connectivity (O(p^{2d}) nonzeros per row), leading to severe memory consumption and memory bandwidth bottlenecks that cap SpMV throughput at under 2% of peak GPU FLOPS. Matrix-free partial assembly bypasses global matrix storage. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Section I, p. 1; Section V.B, p. 5)_ -- **misconception-linear-element-matrix-free-disadvantage**: It is a common misconception that matrix-free operator representations are only beneficial for high-order elements and incur overhead for low-order discretizations. In reality, matrix-free data structures offer up to 2x efficiency benefits even for linear (Q_1) elements compared to assembled CSR sparse matrices. _(Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf, Abstract, p. 1; Section V.B, p. 5)_ - -## References - -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf -- Trotter et al_2023_Targeting performance and user-friendliness.pdf -- Xue et al_2023_JAX-FEM.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-minres.md b/packages/akms/src/akms/_bundled/global_nodes/solver-minres.md deleted file mode 100644 index 7e34037..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-minres.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: solver-minres -title: MINRES for Symmetric Indefinite Systems -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- MINRES -- krylov -- symmetric-indefinite -- saddle-point -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-cg-algorithm - type: contradicts - weight: 0.0 -- to: solver-gmres-algorithm - type: refines - weight: 0.7 -- to: precond-field-split-block - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# MINRES for Symmetric Indefinite Systems - -## Summary - -The Minimal Residual (MR) and Generalized Minimal Residual (GMRES) Krylov subspace iterative methods solve linear systems Ax = b where coefficient matrix A is symmetric indefinite or non-symmetric. Unlike standard Conjugate Gradient (CG), which requires symmetric positive-definite (SPD) operators and fails when encountering non-positive curvature, residual-minimizing Krylov solvers compute solution updates x_m = x_0 + V_m y_m that explicitly minimize the Euclidean residual norm ||b - A x_m||_2 over Krylov subspace K_m(A, r_0), providing robust convergence for saddle-point systems and indefinite block discretizations. - -## 1. Core Concept - -In computational mechanics and constrained optimization, discretized linear systems often exhibit saddle-point block structures \begin{bmatrix} A & B \\ B^T & 0 \end{bmatrix} with zero diagonal blocks for Lagrange multipliers or constraint variables. Because coefficient matrix A is indefinite, applying standard Conjugate Gradient (CG) can lead to division by zero or divergence when p_k^T A p_k \le 0. Residual-minimizing Krylov subspace solvers (such as Minimal Residual and GMRES) circumvent positive-definiteness requirements by constructing orthonormal Krylov basis vectors V_m via the Arnoldi process (or Lanczos process for symmetric systems) such that A V_m = V_{m+1} \bar{H}_m. Solution updates x_m = x_0 + V_m y_m are computed by finding vector y_m that minimizes least-squares residual functional ||\beta e_1 - \bar{H}_m y||_2 via Givens plane rotations. For saddle-point formulations, pairing residual-minimizing Krylov solvers with block field-split preconditioners or Schur complement solvers eliminates indefiniteness bottlenecks. - -## 2. Mathematical Formulation - -**krylov-residual-minimization** -$$ -x_m = x_0 + V_m y_m \quad \text{where } y_m = \arg\min_{y \in \mathbb{R}^m} \|\beta e_1 - \bar{H}_m y\|_2 -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.1, p. 172_ - -**saddle-point-indefinite-system** -$$ -\begin{bmatrix} A & B \\ B^T & 0 \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} b \\ c \end{bmatrix} -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 8.4, p. 268; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 6.1, p. 388_ - -**givens-rotation-least-squares-solve** -$$ -Q_m (\beta e_1 - \bar{H}_m y) = \begin{bmatrix} \bar{g}_m - R_m y \\ \gamma_{m+1} \end{bmatrix} -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.3, pp. 174-177_ - -**Notation:** -A represents global coefficient matrix; x_m represents solution vector at Krylov iteration m; r_0 represents initial residual vector b - A x_0; V_m represents matrix of orthonormal Krylov basis vectors; \bar{H}_m represents upper Hessenberg or tridiagonal matrix; Q_m represents sequence of Givens rotation matrices; \beta represents initial residual Euclidean norm. - - -## 3. Algorithmic Implementation - -**minimal-residual-krylov-algorithm** -$$ -\begin{algorithmic} -\State $r_0 = b - A x_0, \quad \beta = \|r_0\|_2, \quad v_1 = r_0 / \beta$ -\For{$j = 1 \text{ to } m$} -\State $w_j = A v_j \quad \text{(apply linear operator)}$ -\For{$i = 1 \text{ to } j$} -\State $h_{i,j} = (w_j, v_i), \quad w_j \leftarrow w_j - h_{i,j} v_i \quad \text{(orthogonalization sweep)}$ -\EndFor -\State $h_{j+1,j} = \|w_j\|_2, \quad v_{j+1} = w_j / h_{j+1,j}$ -\EndFor -\State $\text{Solve least-squares problem } y_m = \arg\min_y \|\beta e_1 - \bar{H}_m y\|_2 \text{ via Givens plane rotations}$ -\State $x_m = x_0 + V_m y_m$ -\Return $x_m$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.1, p. 172, Algorithm 6.9_ - - -## 4. Known Pitfalls - -- **cg-indefinite-breakdown-in-saddle-point-systems**: Attempting to solve symmetric indefinite saddle-point linear systems \begin{bmatrix} A & B \\ B^T & 0 \end{bmatrix} using standard Conjugate Gradient (CG) causes numerical breakdown or divergence due to non-positive curvature directions p_k^T A p_k \le 0. Using residual-minimizing Krylov solvers (such as GMRES or Minimal Residual methods) guarantees stable, monotonic convergence. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 6.1, p. 214; Section 8.4, p. 268; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 1, p. 3)_ -- **unpreconditioned-indefinite-system-stagnation**: Solving symmetric indefinite or saddle-point linear systems without effective preconditioning leads to wide eigenvalue distributions spanning negative and positive real axes, causing slow Krylov convergence or iteration stagnation. Block-diagonal or Schur complement field-split preconditioners are required to cluster the preconditioned spectrum. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 6.5.5, p. 179; Section 8.4, p. 268; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 3.1, p. 367)_ - -## References - -- IterMethBook_2ndEd.pdf.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-newmark-hht.md b/packages/akms/src/akms/_bundled/global_nodes/solver-newmark-hht.md deleted file mode 100644 index e32d53a..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-newmark-hht.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: solver-newmark-hht -title: 'Implicit Dynamics: Newmark-β & HHT-α' -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- implicit-dynamics -- newmark -- HHT-alpha -- generalized-alpha -- dissipation -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-explicit-dynamics - type: contradicts - weight: 0.0 -- to: solver-imex-splitting - type: refines - weight: 0.7 -- to: solver-pcg-algorithm - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Implicit Dynamics: Newmark-β & HHT-α - -## Summary - -Implicit dynamic time integration methods, such as the Newmark-\beta family, solve discretized transient structural equations M \ddot{d} + C \dot{d} + K d = F using predictor-corrector time stepping. Controlled by parameters \gamma and \beta, implicit Newmark schemes achieve unconditional algorithmic stability when \gamma \ge 1/2 and \beta = (\gamma + 1/2)^2 / 4, enabling large integration time steps unrestricted by Courant-Friedrichs-Lewy (CFL) limits. Setting \gamma = 1/2 yields 2nd-order temporal accuracy without numerical damping, whereas \gamma > 1/2 introduces artificial high-frequency dissipation. - -## 1. Core Concept - -Implicit time integration for structural dynamics solves linear or non-linear semi-discretized equations of motion M a_{n+1} + C v_{n+1} + K d_{n+1} = F_{n+1}. In the classic Newmark-\beta method, displacement and velocity vectors are updated using predictor-corrector approximations governed by integration parameters \gamma \ge 1/2 and \beta \ge (\gamma + 1/2)^2 / 4. In each time step, displacement predictors \tilde{d}_{n+1} and velocity predictors \tilde{v}_{n+1} are evaluated from previous state variables. Substituting these predictors into the semi-discretized balance equation yields an effective linear system K^* d_{n+1} = F_{n+1}^* for updated displacement vector d_{n+1}, where effective tangent stiffness operator K^* = \frac{1}{\beta \Delta t^2} M + \frac{\gamma}{\beta \Delta t} C + K combines mass, damping, and stiffness arrays. Once displacement d_{n+1} is solved, acceleration corrector a_{n+1} and velocity corrector v_{n+1} are calculated. Unconditional stability permits larger time steps \Delta t compared to explicit central difference integration, though solving effective stiffness system K^* d_{n+1} = F_{n+1}^* requires factorizing sparse matrices or executing iterative Krylov solves (such as PCG) at every time step. - -## 2. Mathematical Formulation - -**newmark-displacement-velocity-predictors** -$$ -\tilde{d}_{n+1} = d_n + \Delta t v_n + \frac{\Delta t^2}{2} (1 - 2\beta) a_n, \quad \tilde{v}_{n+1} = v_n + \Delta t (1 - \gamma) a_n -$$ -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 2, p. 376, Eqs. 7-8_ - -**newmark-effective-stiffness-and-force** -$$ -K^* d_{n+1} = F_{n+1}^* \quad \text{where } K^* = \frac{1}{\beta \Delta t^2} M + \frac{\gamma}{\beta \Delta t} C + K -$$ -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 2, p. 376, Eqs. 20-22_ - -**newmark-acceleration-velocity-correctors** -$$ -a_{n+1} = \frac{1}{\beta \Delta t^2} (d_{n+1} - \tilde{d}_{n+1}), \quad v_{n+1} = \tilde{v}_{n+1} + \gamma \Delta t a_{n+1} -$$ -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 2, p. 376, Eqs. 4-5_ - -**newmark-unconditional-stability-condition** -$$ -\gamma \ge \frac{1}{2}, \quad \beta = \frac{1}{4} \left(\gamma + \frac{1}{2}\right)^2 -$$ -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 1, p. 376, Eqs. 16-17_ - -**Notation:** -d_n, v_n, a_n represent nodal displacement, velocity, and acceleration vectors; \tilde{d}_{n+1}, \tilde{v}_{n+1} represent predictor displacement and velocity vectors; M, C, K represent mass, damping, and stiffness matrices; K^* represents effective tangent stiffness matrix; F_{n+1}^* represents effective load vector; \Delta t represents time step size; \gamma, \beta represent Newmark time integration parameters. - - -## 3. Algorithmic Implementation - -**newmark-implicit-transient-algorithm** -$$ -\begin{algorithmic} -\State $\text{Initialize } d_0, v_0, a_0, \text{ mass matrix } M, \text{ damping } C, \text{ stiffness } K, \text{ and parameters } \gamma \ge 1/2, \beta = \frac{1}{4}(\gamma + 1/2)^2$ -\State $\text{Form effective stiffness matrix } K^* = \frac{1}{\beta \Delta t^2} M + \frac{\gamma}{\beta \Delta t} C + K$ -\For{$n = 0, 1, 2, \dots \text{ until } t_n \ge t_{\text{final}}$} -\State $\tilde{d}_{n+1} = d_n + \Delta t v_n + \frac{\Delta t^2}{2} (1 - 2\beta) a_n \quad \text{(displacement predictor)}$ -\State $\tilde{v}_{n+1} = v_n + \Delta t (1 - \gamma) a_n \quad \text{(velocity predictor)}$ -\State $F_{n+1}^* = F_{n+1} + \frac{1}{\beta \Delta t^2} M \tilde{d}_{n+1} - C \left(\tilde{v}_{n+1} - \frac{\gamma \Delta t}{\beta \Delta t^2} \tilde{d}_{n+1}\right) \quad \text{(effective load vector)}$ -\State $\text{Solve linear system } K^* d_{n+1} = F_{n+1}^* \text{ for displacement } d_{n+1} \text{ via PCG or direct solver}$ -\State $a_{n+1} = \frac{1}{\beta \Delta t^2} (d_{n+1} - \tilde{d}_{n+1}) \quad \text{(acceleration corrector)}$ -\State $v_{n+1} = \tilde{v}_{n+1} + \gamma \Delta t a_{n+1} \quad \text{(velocity corrector)}$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 2, p. 376_ - - -## 4. Known Pitfalls - -- **newmark-numerical-dissipation-order-reduction**: In implicit Newmark time integration, setting \gamma > 1/2 introduces artificial numerical damping to suppress spurious high-frequency oscillations, but reduces scheme temporal accuracy from 2nd-order down to 1st-order. _(Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 1, p. 376)_ -- **ill-conditioned-effective-stiffness-at-small-dt**: When time step size \Delta t is extremely small, effective stiffness matrix K^* = \frac{1}{\beta \Delta t^2} M + \frac{\gamma}{\beta \Delta t} C + K becomes dominated by mass scaling term \frac{1}{\beta \Delta t^2} M, causing severe linear solver ill-conditioning if mass matrix M is poorly scaled. _(Source: Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf, Section 2, p. 376; Mass_Scaling.pdf, Section 1, p. 469)_ - -## References - -- Hughes_Liu_1978_Implicit-Explicit Finite Elements in Transient Analysis.pdf -- Mass_Scaling.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/solver-pcg-algorithm.md b/packages/akms/src/akms/_bundled/global_nodes/solver-pcg-algorithm.md deleted file mode 100644 index c536402..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/solver-pcg-algorithm.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -id: solver-pcg-algorithm -title: Preconditioned Conjugate Gradient (PCG) -domain: computational-mechanics -subdomain: solvers -tags: -- solvers -- PCG -- preconditioning -- krylov -- flexible-PCG -status: established -confidence: 0.9 -source: hybrid -edges: -- to: solver-cg-algorithm - type: refines - weight: 0.7 -- to: precond-jacobi-block-jacobi - type: requires - weight: 1.0 -- to: precond-amg-theory - type: requires - weight: 1.0 -- to: precond-ichol-ilu - type: requires - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Preconditioned Conjugate Gradient (PCG) - -## Summary - -The Preconditioned Conjugate Gradient (PCG) algorithm accelerates standard Conjugate Gradient iterations for symmetric positive definite (SPD) linear systems Ax = b by applying a positive definite preconditioning operator M \approx A. By transforming the original system into M^{-1} A x = M^{-1} b and evaluating inner products in the M-norm, PCG clusters operator eigenvalues and reduces condition numbers cond_2(M^{-1} A), lowering iteration counts while requiring only one matrix-vector multiplication, one preconditioner solve, two vector dot products, and three AXPY updates per iteration. - -## 1. Core Concept - -Preconditioned Conjugate Gradient (PCG) solves large, sparse, symmetric positive definite linear systems arising from finite element discretizations of elliptic PDEs, elasticity, and monolithic phase-field fracture models. Unpreconditioned CG convergence depends directly on matrix condition number cond_2(A); for fine finite element meshes, cond_2(A) grows as O(h^{-2}), causing slow convergence. PCG introduces a symmetric positive definite preconditioning matrix M (such as point-Jacobi, block Jacobi IC, or algebraic multigrid AMG) that approximates A. Rather than forming M^{-1} A explicitly, PCG replaces the standard Euclidean inner product with the M-inner product (x, y)_M = (M x, y), ensuring M^{-1} A remains self-adjoint. In each iteration, PCG solves auxiliary linear subproblem M z_k = r_k for preconditioned residual z_k. Direction vectors p_k are maintained M^{-1} A-conjugate, minimizing the error energy norm over preconditioned Krylov subspaces without destroying sparse matrix structure. - -## 2. Mathematical Formulation - -**pcg-step-length-alpha** -$$ -\alpha_j = \frac{(r_j, z_j)}{(A p_j, p_j)} -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 9.2, p. 277, Algorithm 9.1_ - -**pcg-direction-update-beta** -$$ -\beta_j = \frac{(r_{j+1}, z_{j+1})}{(r_j, z_j)} -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 9.2, p. 277, Algorithm 9.1_ - -**m-inner-product-self-adjointness** -$$ -(M^{-1} A x, y)_M = (A x, y) = (x, A y) = (x, M^{-1} A y)_M -$$ -_Source: IterMethBook_2ndEd.pdf.pdf, Section 9.2, p. 276_ - -**Notation:** -A represents global SPD stiffness matrix; M represents SPD preconditioning matrix operator; x_j represents solution vector iterate at step j; b represents load vector; r_j represents residual vector b - A x_j; z_j represents preconditioned residual vector M^{-1} r_j; p_j represents search direction vector; \alpha_j, \beta_j represent scalar update parameters; (\cdot, \cdot) represents Euclidean inner product. - - -## 3. Algorithmic Implementation - -**preconditioned-conjugate-gradient-algorithm** -$$ -\begin{algorithmic} -\State $x_0 \leftarrow \text{Initial guess}, \quad r_0 = b - A x_0, \quad z_0 = M^{-1} r_0 \quad \text{(initial preconditioner solve)}, \quad p_0 = z_0$ -\For{$j = 0, 1, 2, \dots \text{ until } \|r_j\|_2 < \text{tol}$} -\State $w_j = A p_j \quad \text{(single sparse matrix-vector product)}$ -\State $\alpha_j \leftarrow \frac{(r_j, z_j)}{(w_j, p_j)}$ -\State $x_{j+1} \leftarrow x_j + \alpha_j p_j \quad \text{(solution update)}$ -\State $r_{j+1} \leftarrow r_j - \alpha_j w_j \quad \text{(residual update)}$ -\State $z_{j+1} \leftarrow M^{-1} r_{j+1} \quad \text{(preconditioner solve sweep)}$ -\State $\beta_j \leftarrow \frac{(r_{j+1}, z_{j+1})}{(r_j, z_j)}$ -\State $p_{j+1} \leftarrow z_{j+1} + \beta_j p_j \quad \text{(search direction update)}$ -\EndFor -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: IterMethBook_2ndEd.pdf.pdf, Section 9.2, p. 277, Algorithm 9.1; Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 4, p. 9_ - - -## 4. Known Pitfalls - -- **non-spd-preconditioner-breakdown**: PCG strictly requires both system matrix A and preconditioner M to be symmetric positive-definite (SPD) so that M defines a valid inner product (x, y)_M = (M x, y). Applying an indefinite, non-symmetric, or non-linear variable preconditioner (which changes across iterations) destroys operator self-adjointness, leading to loss of search direction A-conjugacy, residual growth, or algorithm breakdown. _(Source: IterMethBook_2ndEd.pdf.pdf, Section 9.2, p. 276; Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf, Section 3.5, p. 375)_ -- **preconditioner-setup-time-dominance**: While sophisticated preconditioners like smoothed aggregation algebraic multigrid (AMG) or incomplete factorizations with higher fill levels dramatically reduce PCG iteration counts, setting up preconditioner operator M^{-1} (t_setup) can consume up to 50% of total solution time. Balancing setup overhead against Krylov iteration reduction is critical for optimizing overall wall-clock performance. _(Source: Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf, Section 5.3.1, p. 22, Fig. 9)_ - -## References - -- IterMethBook_2ndEd.pdf.pdf -- Badri et al_2021_Preconditioning strategies for vectorial finite element linear systems arising.pdf -- Knoll_Keyes_2004_Jacobian-free Newton–Krylov methods.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \$p\$-Multigrid.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/stress-cauchy-kirchhoff.md b/packages/akms/src/akms/_bundled/global_nodes/stress-cauchy-kirchhoff.md deleted file mode 100644 index 9c271b8..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/stress-cauchy-kirchhoff.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -id: stress-cauchy-kirchhoff -title: Cauchy & Kirchhoff Stress -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- stress -- cauchy-stress -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: kinematics-motion-deformation-gradient - type: requires - weight: 0.9 - note: Kirchhoff $\boldsymbol{\tau}=J\boldsymbol{\sigma}$ uses the Jacobian from $\mathbf{F}$ -- to: kinematics-velocity-gradient - type: feeds-into - weight: 1.0 - note: Stress-power conjugacy $\boldsymbol{\sigma}\colon\mathbf{D}=\boldsymbol{\tau}\colon\mathbf{D}/J$ -- to: stress-piola-kirchhoff - type: feeds-into - weight: 1.0 - note: PK1 / PK2 stresses are pull-backs of Cauchy / Kirchhoff to the reference configuration -- to: stress-push-forward-pull-back - type: feeds-into - weight: 1.0 - note: $\boldsymbol{\tau}$ is the natural push-forward target of $\mathbf{S}$ -context_size: small -reading_priority: full -load_with: -- stress-piola-kirchhoff -- stress-push-forward-pull-back -content_ref: null -akms_schema: v2 ---- - -# Cauchy & Kirchhoff Stress - -## Summary -The Cauchy (true) stress $\boldsymbol{\sigma}$ measures force per unit current area: $\mathbf{t}=\boldsymbol{\sigma}\cdot\mathbf{n}$ on a deformed surface. Symmetry $\boldsymbol{\sigma}=\boldsymbol{\sigma}^T$ follows from balance of angular momentum, and the spatial form of equilibrium reads $\nabla\cdot\boldsymbol{\sigma}+\rho\mathbf{b}=\rho\dot{\mathbf{v}}$. The Kirchhoff stress $\boldsymbol{\tau}=J\boldsymbol{\sigma}$ rescales by the Jacobian $J=\det\mathbf{F}$ and is also symmetric. Internal-power densities are equivalent: $\boldsymbol{\sigma}\colon\mathbf{D}\,dv = \boldsymbol{\tau}\colon\mathbf{D}\,(dv/J) = \boldsymbol{\sigma}\colon\mathbf{D}\,J\,dV_0$. Kirchhoff is preferred in finite-strain hyperelasticity because the convected / Truesdell rate $\mathcal{L}_v\boldsymbol{\tau}=\mathbf{F}\dot{\mathbf{S}}\mathbf{F}^T$ is the natural objective stress rate; Cauchy is the form the user reports because it has direct physical-stress units. Conversion is $\boldsymbol{\sigma}=\boldsymbol{\tau}/J$ with care taken that $J>0$. - - -## 1. Core Concept -Cauchy stress is the operational stress in computational mechanics: every traction boundary condition, every "stress" plotted on a deformed mesh, every yield criterion is written in terms of $\boldsymbol{\sigma}$. It is symmetric (angular momentum), it appears in the spatial equation of motion $\nabla\cdot\boldsymbol{\sigma}+\rho\mathbf{b}=\rho\dot{\mathbf{v}}$, and it is the stress users report. Kirchhoff stress $\boldsymbol{\tau}=J\boldsymbol{\sigma}$ is the same physical stress measured per unit reference volume rather than per unit current volume; the rescaling makes it the natural Eulerian companion to PK2 ($\boldsymbol{\tau}=\mathbf{F}\mathbf{S}\mathbf{F}^T$) and gives it a clean pairing with the rate-of-deformation under the Lie derivative ($\mathcal{L}_v\boldsymbol{\tau}=\mathbf{F}\dot{\mathbf{S}}\mathbf{F}^T$ is the convected/Truesdell rate). Because $\boldsymbol{\tau}$ uses reference volumes, mass / momentum balance integrated over $\Omega_0$ in TL-FEM uses $\boldsymbol{\tau}$ implicitly via $\mathbf{S}=\mathbf{F}^{-1}\boldsymbol{\tau}\mathbf{F}^{-T}$. The two stresses are interchangeable through $J$ but are NOT the same tensor; conflating them by a factor $J$ is one of the most common bugs in finite-strain code. - - -## 2. Mathematical Formulation -Throughout, $\Omega_t$ is the current configuration and $\Omega_0$ the reference. $\rho$ is current mass density, $\rho_0$ reference; $\mathbf{b}$ body force per unit mass; $\dot{\mathbf{v}}$ material acceleration; $\mathbf{n}$ unit outward normal on a current surface. Latin lower-case indices are spatial. - - -**Cauchy stress and the traction:** - -$$ -\mathbf{t} = \boldsymbol{\sigma}\cdot\mathbf{n},\qquad -\sigma_{ij} = \sigma_{ji} \quad(\text{angular momentum}) -$$ - -where $\mathbf{t}$ is force per unit current area on a surface with outward normal $\mathbf{n}$ - -**Kirchhoff stress:** - -$$ -\boldsymbol{\tau} = J\,\boldsymbol{\sigma},\qquad -\tau_{ij} = J\,\sigma_{ij},\qquad -J = \det\mathbf{F} > 0 -$$ - -where $\boldsymbol{\tau}$ is symmetric for the same reason as $\boldsymbol{\sigma}$ - -**Spatial equilibrium / equation of motion:** - -$$ -\nabla\cdot\boldsymbol{\sigma} + \rho\,\mathbf{b} = \rho\,\dot{\mathbf{v}}, -\qquad -\frac{\partial \sigma_{ij}}{\partial x_j} + \rho\,b_i = \rho\,\dot v_i -$$ - -where Statics recovers $\nabla\cdot\boldsymbol{\sigma}+\rho\mathbf{b}=0$ - -**Traction transformation (Cauchy <-> reference area):** - -$$ -\mathbf{t}\,da = \boldsymbol{\sigma}\cdot\mathbf{n}\,da - = J\,\boldsymbol{\sigma}\cdot\mathbf{F}^{-T}\cdot\mathbf{n}_0\,dA_0 - = \mathbf{P}\cdot\mathbf{n}_0\,dA_0 -$$ - -where $\mathbf{P}=J\boldsymbol{\sigma}\mathbf{F}^{-T}$ is the nominal stress (PK1) - -**Mass conservation:** - -$$ -\rho_0 = J\,\rho,\qquad -\int_{\Omega_0}\rho_0\,dV_0 = \int_{\Omega_t}\rho\,dv -$$ - -where Trivial consequence of $dv=J\,dV_0$ - -**Stress-power equivalence:** - -$$ -\boldsymbol{\sigma}\colon\mathbf{D}\,dv = \boldsymbol{\tau}\colon\mathbf{D}\,\frac{dv}{J} = \boldsymbol{\tau}\colon\mathbf{D}\,dV_0 -$$ - -where $\boldsymbol{\sigma}\colon\mathbf{D}$ is power per current volume; $\boldsymbol{\tau}\colon\mathbf{D}$ is power per reference volume - -**Material time derivative of $\boldsymbol{\tau}$:** - -$$ -\dot{\boldsymbol{\tau}} = J\,\dot{\boldsymbol{\sigma}} + \boldsymbol{\sigma}\,\mathrm{tr}\,\mathbf{D}\,J - = J\,(\dot{\boldsymbol{\sigma}} + \boldsymbol{\sigma}\,\mathrm{tr}\,\mathbf{L}), -\qquad \dot J = J\,\mathrm{tr}\,\mathbf{L} = J\,\mathrm{tr}\,\mathbf{D} -$$ - -where Used when relating spatial constitutive rates expressed in $\boldsymbol{\sigma}$ vs $\boldsymbol{\tau}$ - -**Lie / convected rate of $\boldsymbol{\tau}$:** - -$$ -\mathcal{L}_v\,\boldsymbol{\tau} -= \dot{\boldsymbol{\tau}} - \mathbf{L}\,\boldsymbol{\tau} - \boldsymbol{\tau}\,\mathbf{L}^T -= \mathbf{F}\,\dot{\mathbf{S}}\,\mathbf{F}^T -$$ - -where Naturally objective; the canonical stress rate in finite-strain hyperelasticity (`tensor-operations`) - -**Decompositions: hydrostatic vs deviatoric:** - -$$ -p = -\tfrac{1}{3}\,\mathrm{tr}\,\boldsymbol{\sigma},\qquad -\mathbf{s} = \boldsymbol{\sigma} + p\,\mathbf{I},\qquad -\boldsymbol{\sigma} = -p\,\mathbf{I} + \mathbf{s} -$$ - -where Pressure / deviator split used in nearly-incompressible and J2 plasticity - -**Notation:** - -- $\boldsymbol{\sigma}$ — Cauchy (true) stress, force per unit current area -- $\boldsymbol{\tau}$ — Kirchhoff stress, $\boldsymbol{\tau}=J\boldsymbol{\sigma}$ -- $J$ — Jacobian, $J=\det\mathbf{F}>0$ -- $\mathbf{t}$ — Traction vector on a current surface -- $\mathbf{n},\mathbf{n}_0$ — Current / reference outward unit normals -- $p$ — Hydrostatic pressure, $p=-\tfrac13\mathrm{tr}\,\boldsymbol{\sigma}$ -- $\mathbf{s}$ — Deviatoric stress, $\mathbf{s}=\boldsymbol{\sigma}+p\mathbf{I}$ -- $\mathcal{L}_v\boldsymbol{\tau}$ — Lie / convected derivative of $\boldsymbol{\tau}$ - - -## 3. Algorithmic Implementation -**Algorithm: Convert Between Cauchy and Kirchhoff Stress** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \boldsymbol{\sigma}\,\text{or}\,\boldsymbol{\tau},\,\mathbf{F}$ -\State $J \gets \det\mathbf{F}$ -\If{$J \le J_{\min}$} -\State $\text{abort: element inverted, conversion undefined}$ -\EndIf -\State $\boldsymbol{\tau} \gets J\,\boldsymbol{\sigma}\;\text{or}\;\boldsymbol{\sigma} \gets \boldsymbol{\tau}/J$ -\Return $\boldsymbol{\tau}\,\text{or}\,\boldsymbol{\sigma}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -`@ti.func` per Gauss point. Pre-compute $J$ once with the deformation gradient (cofactor / determinant) and cache it so the conversion is a single multiply per stress component. Tag every stress array with `_cauchy` or `_kirchhoff` to make the convention explicit at every interface. - - -**Algorithm: Hydrostatic / Deviatoric Split** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \boldsymbol{\sigma}\in\mathbb{R}^{3\times 3}_{\mathrm{sym}}$ -\State $p \gets -\tfrac{1}{3}(\sigma_{11}+\sigma_{22}+\sigma_{33})$ -\For{$i,j = 1,2,3$} -\State $s_{ij} \gets \sigma_{ij} + p\,\delta_{ij}$ -\EndFor -\Return $p,\,\mathbf{s}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Inline `@ti.func`; six FMAs. Reuse for J2-plasticity yield evaluations $f=\sqrt{3J_2}-\sigma_Y$ where $J_2=\tfrac12 s_{ij}s_{ij}$ (cf. `tensor-invariants`). The split is structurally identical for $\boldsymbol{\tau}$ and $\boldsymbol{\sigma}$; pick whichever is already in registers. - - -**Algorithm: Equilibrium Residual on a Current-Configuration Mesh (UL-FEM)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \boldsymbol{\sigma}\,\text{at GPs},\,\rho,\mathbf{b},\,\text{nodal}\,\dot{\mathbf{v}}$ -\State $\mathbf{f}^{\mathrm{int}}_a \gets \int_{\Omega_t} \mathbf{B}_a^T\colon\boldsymbol{\sigma}\,dv$ -\State $\mathbf{f}^{\mathrm{ext}}_a \gets \int_{\Omega_t} N_a\,\rho\,\mathbf{b}\,dv + \int_{\partial\Omega_t} N_a\,\bar{\mathbf{t}}\,da$ -\State $\mathbf{r}_a \gets \mathbf{f}^{\mathrm{int}}_a - \mathbf{f}^{\mathrm{ext}}_a + \mathbf{M}_{ab}\,\dot{\mathbf{v}}_b$ -\Return $\mathbf{r}_a$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Updated-Lagrangian assembly uses $\boldsymbol{\sigma}$ directly. For TL-FEM convert to PK2 first (`stress-piola-kirchhoff`). The B-matrix is the spatial gradient of shape functions. Use `ti.atomic_add` for the global force scatter; pre-compute $dv=J\,dV_0$ at each Gauss point. - - - -## 4. Known Pitfalls -**Confusing $\boldsymbol{\sigma}$ with $\boldsymbol{\tau}$:** $\boldsymbol{\tau}=J\boldsymbol{\sigma}$ — they differ by the Jacobian. Plotting $\boldsymbol{\tau}$ where the user expects $\boldsymbol{\sigma}$ overestimates "stress" by $J$ (e.g., 50% at $J=1.5$). Tag every output stress with its convention; provide a single-point-of-conversion utility rather than ad-hoc inline rescaling. - - -**Forgetting $\boldsymbol{\sigma}=\boldsymbol{\sigma}^T$:** Angular momentum balance enforces $\boldsymbol{\sigma}=\boldsymbol{\sigma}^T$. Numerical algorithms (especially incremental rotation updates, Hughes-Winget) can drift off symmetry by round-off; over many steps the asymmetry builds and corrupts the equilibrium residual. Symmetrise $\boldsymbol{\sigma}\to\tfrac12(\boldsymbol{\sigma}+\boldsymbol{\sigma}^T)$ at the end of every constitutive update. - - -**Mixing reference and current divergence operators:** Spatial equilibrium is $\nabla\cdot\boldsymbol{\sigma}+\rho\mathbf{b}=\rho\dot{\mathbf{v}}$ on $\Omega_t$; reference equilibrium is $\nabla_0\cdot\mathbf{P}+\rho_0\mathbf{b}_0=\rho_0\dot{\mathbf{v}}$ on $\Omega_0$. Using a material gradient on $\boldsymbol{\sigma}$ or a spatial gradient on $\mathbf{P}$ produces residuals off by an integration over the wrong configuration. Decide UL or TL once, document, validate. - - -**Sign convention on traction / normal:** $\mathbf{t}=\boldsymbol{\sigma}\cdot\mathbf{n}$ assumes $\mathbf{n}$ is the OUTWARD unit normal. A common bug in contact / surface-load assembly is using the inward normal, flipping the sign of every applied traction. Document the convention at the boundary-condition API and validate with a uniaxial-tension benchmark. - - -**Element inversion makes $\boldsymbol{\tau}/J$ singular:** As $J\to 0$ the conversion $\boldsymbol{\sigma}=\boldsymbol{\tau}/J$ blows up. Detect $J0$. Lower-case Latin = spatial; upper-case Latin = material. Density: $\rho_0=J\rho$. - - -**PK1 (nominal) stress:** - -$$ -\mathbf{P} = J\,\boldsymbol{\sigma}\,\mathbf{F}^{-T},\qquad -P_{iJ} = J\,\sigma_{ij}\,F^{-1}_{Jj} -$$ - -where Two-point tensor; lower-case spatial $i$, upper-case material $J$ - -**Traction transformation:** - -$$ -\mathbf{t}\,da = \mathbf{P}\cdot\mathbf{n}_0\,dA_0,\qquad -\int_{\partial\Omega_t}\mathbf{t}\,da = \int_{\partial\Omega_0}\mathbf{P}\cdot\mathbf{n}_0\,dA_0 -$$ - -where Same physical force, integrated over reference vs current surface - -**PK2 stress:** - -$$ -\mathbf{S} = \mathbf{F}^{-1}\mathbf{P} = J\,\mathbf{F}^{-1}\boldsymbol{\sigma}\,\mathbf{F}^{-T},\qquad -S_{IJ} = J\,F^{-1}_{Ii}\,\sigma_{ij}\,F^{-1}_{Jj} -$$ - -where Fully Lagrangian (both indices material); symmetric $\mathbf{S}=\mathbf{S}^T$ since $\boldsymbol{\sigma}$ symmetric - -**Inverse transformations:** - -$$ -\boldsymbol{\sigma} = J^{-1}\,\mathbf{P}\,\mathbf{F}^T = J^{-1}\,\mathbf{F}\,\mathbf{S}\,\mathbf{F}^T,\qquad -\boldsymbol{\tau} = \mathbf{F}\,\mathbf{S}\,\mathbf{F}^T = \mathbf{P}\,\mathbf{F}^T -$$ - -where Recover spatial stresses from Lagrangian; $\boldsymbol{\tau}=J\boldsymbol{\sigma}$ - -**Symmetry contrast:** - -$$ -\mathbf{S} = \mathbf{S}^T \;(\text{symmetric}),\qquad -\mathbf{P} \ne \mathbf{P}^T \;\text{in general} -$$ - -where $\mathbf{P}$ asymmetric because the two legs live in different configurations - -**Reference-configuration equation of motion:** - -$$ -\nabla_0\cdot\mathbf{P} + \rho_0\,\mathbf{b}_0 = \rho_0\,\dot{\mathbf{v}},\qquad -\frac{\partial P_{iJ}}{\partial X_J} + \rho_0\,b_{0,i} = \rho_0\,\dot v_i -$$ - -where Lagrangian counterpart of the spatial $\nabla\cdot\boldsymbol{\sigma}+\rho\mathbf{b}=\rho\dot{\mathbf{v}}$ - -**Conjugacy table:** - -$$ -\mathbf{P}\colon\dot{\mathbf{F}} = \mathbf{S}\colon\dot{\mathbf{E}} - = \boldsymbol{\tau}\colon\mathbf{D} - = J\,\boldsymbol{\sigma}\colon\mathbf{D}, -\qquad \dot{\mathbf{E}} = \tfrac{1}{2}\dot{\mathbf{C}} = \mathbf{F}^T\,\mathbf{D}\,\mathbf{F} -$$ - -where Internal-power density per reference volume; all four expressions are equal - -**Hyperelastic PK2:** - -$$ -\mathbf{S} = 2\,\frac{\partial \psi(\mathbf{C})}{\partial \mathbf{C}} - = \frac{\partial \psi(\mathbf{E})}{\partial \mathbf{E}} -$$ - -where Same stress through $\mathbf{C}$- or $\mathbf{E}$-parameterised energy; factor 2 absorbs $\mathbf{E}=\tfrac12(\mathbf{C}-\mathbf{I})$ - -**Convected (Lie) rate of $\boldsymbol{\tau}$ from $\dot{\mathbf{S}}$:** - -$$ -\mathcal{L}_v\,\boldsymbol{\tau} = \mathbf{F}\,\dot{\mathbf{S}}\,\mathbf{F}^T -$$ - -where Truesdell rate of Cauchy stress equals $J^{-1}\,\mathcal{L}_v\boldsymbol{\tau}$ - -**Notation:** - -- $\mathbf{P}$ — First Piola-Kirchhoff (nominal) stress, $\mathbf{P}=J\boldsymbol{\sigma}\mathbf{F}^{-T}$ -- $\mathbf{S}$ — Second Piola-Kirchhoff stress, $\mathbf{S}=J\mathbf{F}^{-1}\boldsymbol{\sigma}\mathbf{F}^{-T}$ -- $\boldsymbol{\sigma}$ — Cauchy stress (`stress-cauchy-kirchhoff`) -- $\boldsymbol{\tau}$ — Kirchhoff stress, $\boldsymbol{\tau}=J\boldsymbol{\sigma}=\mathbf{F}\mathbf{S}\mathbf{F}^T$ -- $\mathbf{F},J$ — Deformation gradient and Jacobian -- $\mathbf{E}$ — Green-Lagrange strain, $\mathbf{E}=\tfrac12(\mathbf{C}-\mathbf{I})$ -- $\dot{\mathbf{F}},\dot{\mathbf{E}}$ — Material time derivatives, work-conjugate to $\mathbf{P},\mathbf{S}$ -- $\rho_0,\mathbf{b}_0$ — Reference density and reference-frame body force -- $\nabla_0$ — Material (reference) gradient, $\partial/\partial\mathbf{X}$ - - -## 3. Algorithmic Implementation -**Algorithm: Compute $\mathbf{P}$ and $\mathbf{S}$ from $\boldsymbol{\sigma}$ and $\mathbf{F}$** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \boldsymbol{\sigma}\in\mathbb{R}^{3\times 3}_{\mathrm{sym}},\,\mathbf{F}\in\mathbb{R}^{3\times 3}$ -\State $J \gets \det\mathbf{F}$ -\State $\mathbf{F}^{-1} \gets \mathrm{cofactor\;inverse}(\mathbf{F})$ -\State $\mathbf{P} \gets J\,\boldsymbol{\sigma}\,\mathbf{F}^{-T}$ -\State $\mathbf{S} \gets \mathbf{F}^{-1}\,\mathbf{P} = J\,\mathbf{F}^{-1}\,\boldsymbol{\sigma}\,\mathbf{F}^{-T}$ -\State $\mathbf{S} \gets \tfrac{1}{2}(\mathbf{S}+\mathbf{S}^T) \;\text{(symmetrise to suppress round-off skew)}$ -\Return $\mathbf{P},\,\mathbf{S}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -`@ti.func` per Gauss point. Cache $\mathbf{F}^{-1}$ once at the start of the constitutive update — reuse for $\mathbf{P}$, $\mathbf{S}$, and any push-forward / pull-back routine. Symmetrise $\mathbf{S}$ at construction even though it is mathematically symmetric — round-off in $\boldsymbol{\sigma}$ and $\mathbf{F}^{-1}$ produces $\mathcal{O}(10^{-14})$ skew that integrates to wrong moments over many time steps. Store $\mathbf{S}$ as 6 components, $\mathbf{P}$ as full 9. - - -**Algorithm: Hyperelastic PK2 from Strain-Energy Potential** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{F},\;\psi(\mathbf{C})\;\text{or}\;\psi(\mathbf{E})$ -\State $\mathbf{C} \gets \mathbf{F}^T\,\mathbf{F}$ -\State $\mathbf{S} \gets 2\,\frac{\partial \psi(\mathbf{C})}{\partial \mathbf{C}} \;\text{or}\; \mathbf{S} \gets \frac{\partial \psi(\mathbf{E})}{\partial \mathbf{E}}$ -\State $\boldsymbol{\sigma} \gets J^{-1}\,\mathbf{F}\,\mathbf{S}\,\mathbf{F}^T$ -\Return $\mathbf{S},\,\boldsymbol{\sigma}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -For invariant-based $\psi(I_1,I_2,I_3)$ use the chain rule $\mathbf{S}=2\sum_k(\partial\psi/\partial I_k)(\partial I_k/\partial\mathbf{C})$ from `tensor-derivatives-scalars`. For incompressible Mooney-Rivlin add a Lagrange multiplier $-p\,J\mathbf{C}^{-1}$ to enforce $J=1$. The push-forward $\boldsymbol{\sigma}=J^{-1}\mathbf{F}\mathbf{S}\mathbf{F}^T$ is the canonical use of `stress-push-forward-pull-back`. - - -**Algorithm: TL-FEM Internal Force from PK2** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{S}\,\text{at GPs},\,\mathbf{F},\,\partial N_a/\partial \mathbf{X}$ -\For{$\text{each Gauss point}$} -\State $\mathbf{P} \gets \mathbf{F}\,\mathbf{S}$ -\For{$a = 1,\ldots,n_n;\,i,J = 1,2,3$} -\State $f^{\mathrm{int}}_{a,i} \mathrel{+}= P_{iJ}\,(\partial N_a/\partial X_J)\,W\,\det(\partial \mathbf{X}/\partial \boldsymbol{\xi})$ -\EndFor -\EndFor -\Return $\mathbf{f}^{\mathrm{int}}_a$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -The reference-configuration B-matrix $B_{aiJ}=\partial N_a/\partial X_J$ is constant in time — pre-compute once per element. The kernel is $\mathbf{f}^{\mathrm{int}}_a=\sum_{\mathrm{GP}}(\mathbf{F}\mathbf{S})\cdot(\partial N_a/\partial\mathbf{X})\,W_{\mathrm{GP}}\,\det J_{\mathrm{ref}}$; scatter to the global force vector with `ti.atomic_add`. Avoid converting to $\boldsymbol{\sigma}$ inside the assembly loop — it costs an extra inverse-transpose per Gauss point. - - - -## 4. Known Pitfalls -**$\mathbf{P}$ is not symmetric:** $P_{iJ}$ is a two-point tensor: $\mathbf{P}\ne\mathbf{P}^T$ except in trivial cases (pure dilation). Storing it in 6-component symmetric form drops the skew part and corrupts the reference equilibrium $\nabla_0\cdot\mathbf{P}$. Store $\mathbf{P}$ as full 9 components; reserve symmetric storage for $\mathbf{S}$ and $\boldsymbol{\sigma}$. - - -**Mixing material and spatial divergences:** Reference equilibrium uses the material divergence $\partial P_{iJ}/\partial X_J$, NOT the spatial $\partial P_{ij}/\partial x_j$. The two give different residuals because they integrate against different reference / current geometries. TL-FEM kernels must use $\partial N_a/\partial \mathbf{X}$; UL-FEM must use $\partial N_a/\partial \mathbf{x}$. Mixing them silently halves or doubles the assembled residual. - - -**Sign / order convention on $\mathbf{F}^{-1}$:** $\mathbf{S}=\mathbf{F}^{-1}\mathbf{P}$, NOT $\mathbf{P}\mathbf{F}^{-1}$ — the inverse acts on the LEFT to remove the spatial leg of $\mathbf{P}$. Swapping the order produces a tensor with mixed legs that is neither $\mathbf{S}$ nor $\boldsymbol{\sigma}$ and corrupts every downstream stress operation. Always derive the formula in indicial form: $S_{IJ}=F^{-1}_{Ii}\,P_{iJ}$. - - -**Conjugacy bookkeeping:** $\mathbf{S}\colon\dot{\mathbf{E}}\,dV_0$ is the correct internal-power density per reference volume. Pairing $\mathbf{S}\colon\mathbf{D}$ (Cauchy strain rate) is dimensionally consistent but conceptually wrong and breaks energy balance under finite rotation. Tag every stress / strain pairing with its conjugate partner and validate with a closed-loop deformation cycle. - - -**Index ordering in $\mathbf{S}=\mathbf{F}^{-1}\boldsymbol{\sigma}\mathbf{F}^{-T}$:** The full pull-back is $S_{IJ}=J\,F^{-1}_{Ii}\,\sigma_{ij}\,F^{-1}_{Jj}$ — both inverses act on the LEFT of their respective indices, transposing the second one to give the right-leg multiplication. A common bug is using $\mathbf{F}^{-T}$ on the left instead of $\mathbf{F}^{-1}$, producing a transposed-and-mirrored tensor. Always derive component-wise first; only then write in compact form. - - -**Forgetting the $J$ factor:** $\mathbf{S}=J\mathbf{F}^{-1}\boldsymbol{\sigma}\mathbf{F}^{-T}$ — the $J$ is essential. Dropping it gives $\mathbf{F}^{-1}\boldsymbol{\sigma}\mathbf{F}^{-T}=J^{-1}\mathbf{S}$ which is wrong by a factor $J$ (significant at large strain). Equivalent statement: $\boldsymbol{\tau}=\mathbf{F}\mathbf{S}\mathbf{F}^T$ (no $J$) but $\boldsymbol{\sigma}=J^{-1}\mathbf{F}\mathbf{S}\mathbf{F}^T$. - - -**Numerical asymmetry in $\mathbf{S}$:** $\mathbf{S}$ is mathematically symmetric (inherits from $\boldsymbol{\sigma}$) but round-off in $\mathbf{F}^{-1}$ can produce skew-symmetric noise of $\mathcal{O}(10^{-14})$. Over thousands of steps this drifts into $\mathcal{O}(10^{-8})$ asymmetry, breaks angular-momentum balance, and corrupts the consistent-tangent symmetry. Symmetrise $\mathbf{S}\to\tfrac12(\mathbf{S}+\mathbf{S}^T)$ at the end of every constitutive update. - - -## 5. References -- Belytschko, Liu, Moran & Elkhodary (2014) — Nonlinear Finite Elements for Continua and Structures, 2nd ed. (PK1, PK2 definitions, Piola transformation, conjugacy table, reference equilibrium) -- Holzapfel (2000) — Nonlinear Solid Mechanics (Piola-Kirchhoff stresses, hyperelastic $\mathbf{S}=2\partial\psi/\partial\mathbf{C}$) -- de Borst, Crisfield, Remmers & Verhoosel (2012) — Nonlinear Finite Element Analysis of Solids and Structures, 2nd ed. (TL-FEM internal force assembly using PK2) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/stress-push-forward-pull-back.md b/packages/akms/src/akms/_bundled/global_nodes/stress-push-forward-pull-back.md deleted file mode 100644 index d2de605..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/stress-push-forward-pull-back.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -id: stress-push-forward-pull-back -title: Push-Forward & Pull-Back of Stress -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- push-forward -- pull-back -status: tentative -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: stress-piola-kirchhoff - type: requires - weight: 1.0 - note: Push-forward of PK2 to Kirchhoff and pull-back of Cauchy to PK2 -- to: stress-cauchy-kirchhoff - type: requires - weight: 1.0 - note: $\boldsymbol{\tau}=\mathbf{F}\mathbf{S}\mathbf{F}^T$, $\boldsymbol{\sigma}=\boldsymbol{\tau}/J$ -- to: tensor-operations - type: refines - weight: 0.7 - note: Specialises generic push-forward / pull-back to stress (kinetic, contravariant-contravariant) tensors -- to: kinematics-objective-rates - type: feeds-into - weight: 0.9 - note: Lie / Truesdell rate $\mathcal{L}_v\boldsymbol{\tau}=\mathbf{F}\dot{\mathbf{S}}\mathbf{F}^T$ -- to: stress-tangent-push-forward - type: feeds-into - weight: 1.0 - note: Constitutive tangent push-forward extends the same idea to the 4th-order moduli -context_size: medium -reading_priority: full -load_with: -- stress-piola-kirchhoff -- stress-cauchy-kirchhoff -content_ref: null -akms_schema: v2 ---- - -# Push-Forward & Pull-Back of Stress - -## Summary -Stress is a kinetic (contravariant-contravariant) 2nd-order tensor, so its push-forward / pull-back uses the kinetic rule $\phi_*(\bullet)=\mathbf{F}(\bullet)\mathbf{F}^T$ and $\phi^*(\bullet)=\mathbf{F}^{-1}(\bullet)\mathbf{F}^{-T}$. Concretely: $\boldsymbol{\tau}=\phi_*(\mathbf{S})=\mathbf{F}\mathbf{S}\mathbf{F}^T$ pushes PK2 forward to Kirchhoff stress; $\mathbf{S}=\phi^*(\boldsymbol{\tau})=\mathbf{F}^{-1}\boldsymbol{\tau}\mathbf{F}^{-T}$ pulls Kirchhoff back to PK2. Cauchy stress satisfies $\boldsymbol{\sigma}=J^{-1}\boldsymbol{\tau}$. The Piola transformation $\mathbf{P}=\mathbf{F}\mathbf{S}=J\boldsymbol{\sigma}\mathbf{F}^{-T}$ produces the nominal stress (PK1) — a two-point tensor — by leaving one material leg of $\mathbf{S}$ untouched. The Lie / convected rate $\mathcal{L}_v\boldsymbol{\tau}=\mathbf{F}\dot{\mathbf{S}}\mathbf{F}^T$ is precisely the push-forward of $\dot{\mathbf{S}}$ and is the canonical objective stress rate. Applying the kinematic rule $\mathbf{F}^{-T}(\bullet)\mathbf{F}^{-1}$ to a stress silently destroys symmetry / power conjugacy — the variance of the tensor MUST drive the choice of rule. - - -## 1. Core Concept -Stress is a "contravariant-contravariant" tensor: both legs are upper indices that transform with $\mathbf{F}$ rather than with $\mathbf{F}^{-T}$. The kinetic push-forward rule $\phi_*(\bullet)=\mathbf{F}(\bullet)\mathbf{F}^T$ therefore takes PK2 (fully Lagrangian) to Kirchhoff (fully Eulerian); the pull-back $\phi^*(\bullet)=\mathbf{F}^{-1}(\bullet)\mathbf{F}^{-T}$ goes the other way. The pair is forced by power conjugacy: $\boldsymbol{\tau}\colon\mathbf{D}=\mathbf{S}\colon\dot{\mathbf{E}}$ holds because the $\mathbf{F}\bullet\mathbf{F}^T$ on the stress side cancels the $\mathbf{F}^{-T}\bullet\mathbf{F}^{-1}$ on the strain rate side. The first Piola-Kirchhoff (nominal) stress $\mathbf{P}=\mathbf{F}\mathbf{S}$ is a "half push-forward" — it leaves one material leg of $\mathbf{S}$ untouched, producing a two-point tensor that lives between the configurations. Lie / convected derivatives are constructed by chaining pull-back, time derivative, push-forward, which makes them inherit objectivity from the structure of the chain itself rather than from any extra correction term. - - -## 2. Mathematical Formulation -All operations are with respect to the deformation gradient $\mathbf{F}$ at a single material point. Symmetric stress tensors are stored in 6-component form; the asymmetric $\mathbf{P}$ stays in 9-component form. $J=\det\mathbf{F}>0$. - - -**Kinetic push-forward / pull-back rule:** - -$$ -\phi_*(\bullet) = \mathbf{F}\,(\bullet)\,\mathbf{F}^T,\qquad -\phi^*(\bullet) = \mathbf{F}^{-1}\,(\bullet)\,\mathbf{F}^{-T} -$$ - -where Applies to all kinetic (contravariant-contravariant) tensors - -**PK2 -> Kirchhoff (push-forward):** - -$$ -\boldsymbol{\tau} = \phi_*(\mathbf{S}) = \mathbf{F}\,\mathbf{S}\,\mathbf{F}^T,\qquad -\tau_{ij} = F_{iI}\,F_{jJ}\,S_{IJ} -$$ - -where Indicial form is unambiguous; Voigt $6\times 6$ flattening cannot reproduce this directly - -**Kirchhoff -> PK2 (pull-back):** - -$$ -\mathbf{S} = \phi^*(\boldsymbol{\tau}) = \mathbf{F}^{-1}\,\boldsymbol{\tau}\,\mathbf{F}^{-T},\qquad -S_{IJ} = F^{-1}_{Ii}\,F^{-1}_{Jj}\,\tau_{ij} -$$ - -where Inverse pair: $\phi^*\circ\phi_*=\mathrm{id}$ - -**Cauchy via Kirchhoff:** - -$$ -\boldsymbol{\sigma} = J^{-1}\,\boldsymbol{\tau} = J^{-1}\,\mathbf{F}\,\mathbf{S}\,\mathbf{F}^T,\qquad -\mathbf{S} = J\,\mathbf{F}^{-1}\,\boldsymbol{\sigma}\,\mathbf{F}^{-T} -$$ - -where Same kinetic rule with the Jacobian rescaling - -**Piola transformation (PK2 -> PK1):** - -$$ -\mathbf{P} = \mathbf{F}\,\mathbf{S} = J\,\boldsymbol{\sigma}\,\mathbf{F}^{-T},\qquad -P_{iJ} = F_{iI}\,S_{IJ} -$$ - -where Half push-forward: only the spatial leg is taken forward; PK1 is a two-point tensor - -**Lie / convected rate of Kirchhoff:** - -$$ -\mathcal{L}_v\,\boldsymbol{\tau} = \phi_*\!\left(\frac{D}{Dt}\,\phi^*(\boldsymbol{\tau})\right) - = \phi_*(\dot{\mathbf{S}}) - = \mathbf{F}\,\dot{\mathbf{S}}\,\mathbf{F}^T -$$ - -where Construction: pull back, take material derivative on the reference frame, push forward - -**Spatial expansion of $\mathcal{L}_v\boldsymbol{\tau}$:** - -$$ -\mathcal{L}_v\,\boldsymbol{\tau} -= \dot{\boldsymbol{\tau}} - \mathbf{L}\,\boldsymbol{\tau} - \boldsymbol{\tau}\,\mathbf{L}^T -$$ - -where Equivalent to the convected / Truesdell rate of $J\boldsymbol{\sigma}$ (`tensor-operations`) - -**Kinetic vs kinematic — DO NOT confuse:** - -$$ -\text{Kinetic (stress)} \colon\;\; - \phi_*(\boldsymbol{\sigma}\text{-like}) = \mathbf{F}(\bullet)\mathbf{F}^T,\quad -\text{Kinematic (strain rate)} \colon\;\; - \phi_*(\mathbf{D}\text{-like}) = \mathbf{F}^{-T}(\bullet)\mathbf{F}^{-1} -$$ - -where Variance forces the rule; mixing them breaks $\boldsymbol{\tau}\colon\mathbf{D}=\mathbf{S}\colon\dot{\mathbf{E}}$ - -**Notation:** - -- $\phi_*,\phi^*$ — Push-forward / pull-back operators -- $\mathbf{F}$ — Deformation gradient -- $J$ — $J=\det\mathbf{F}$ -- $\mathbf{S}$ — Second Piola-Kirchhoff (Lagrangian, kinetic) -- $\boldsymbol{\tau}$ — Kirchhoff (Eulerian, kinetic), $\boldsymbol{\tau}=\mathbf{F}\mathbf{S}\mathbf{F}^T$ -- $\boldsymbol{\sigma}$ — Cauchy stress, $\boldsymbol{\sigma}=\boldsymbol{\tau}/J$ -- $\mathbf{P}$ — First Piola-Kirchhoff / nominal stress, two-point -- $\dot{\mathbf{S}}$ — Material time derivative of $\mathbf{S}$ -- $\mathcal{L}_v$ — Lie / convected derivative -- $\mathbf{L}$ — Spatial velocity gradient - - -## 3. Algorithmic Implementation -**Algorithm: Push-Forward $\mathbf{S}\to\boldsymbol{\tau}$ (Symmetric Output)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{S}\in\mathbb{R}^{3\times 3}_{\mathrm{sym}},\,\mathbf{F}$ -\State $\mathbf{T} \gets \mathbf{S}\,\mathbf{F}^T \;(\,T_{Ij} = S_{IK}\,F_{jK}\,)$ -\State $\boldsymbol{\tau} \gets \mathbf{F}\,\mathbf{T} \;(\,\tau_{ij} = F_{iI}\,T_{Ij}\,)$ -\State $\boldsymbol{\tau} \gets \tfrac{1}{2}(\boldsymbol{\tau} + \boldsymbol{\tau}^T) \;\text{(symmetrise — round-off guard)}$ -\Return $\boldsymbol{\tau}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -`@ti.func` per Gauss point. Two $3\times 3$ matrix multiplies = 54 FMAs. Symmetrise even though it is mathematically symmetric: round-off in $\mathbf{F}$ can produce $\mathcal{O}(10^{-14})$ skew that integrates over many time steps. Reuse the cached $\mathbf{F}$ from the deformation-gradient computation — do not recompute it. - - -**Algorithm: Pull-Back $\boldsymbol{\sigma}\to\mathbf{S}$** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \boldsymbol{\sigma}\in\mathbb{R}^{3\times 3}_{\mathrm{sym}},\,\mathbf{F},\,J$ -\State $\mathbf{F}^{-1} \gets \mathrm{cofactor\;inverse}(\mathbf{F})$ -\State $\mathbf{T} \gets \boldsymbol{\sigma}\,\mathbf{F}^{-T}$ -\State $\mathbf{S} \gets J\,\mathbf{F}^{-1}\,\mathbf{T}$ -\State $\mathbf{S} \gets \tfrac{1}{2}(\mathbf{S} + \mathbf{S}^T)$ -\Return $\mathbf{S}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Use after a UL-FEM constitutive update where $\boldsymbol{\sigma}$ is the natural output but the FEM residual lives on the reference configuration. Cache $\mathbf{F}^{-1}$; reuse for the corresponding tangent push-forward. For total-Lagrangian codes the pull-back is rarely needed inside the loop because $\mathbf{S}$ is computed directly. - - -**Algorithm: Lie Rate via Pull-Back / Push-Forward** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \boldsymbol{\tau}_n,\boldsymbol{\tau}_{n+1},\mathbf{F}_n,\mathbf{F}_{n+1},\Delta t$ -\State $\mathbf{S}_n \gets \mathbf{F}_n^{-1}\,\boldsymbol{\tau}_n\,\mathbf{F}_n^{-T}$ -\State $\mathbf{S}_{n+1} \gets \mathbf{F}_{n+1}^{-1}\,\boldsymbol{\tau}_{n+1}\,\mathbf{F}_{n+1}^{-T}$ -\State $\dot{\mathbf{S}} \gets (\mathbf{S}_{n+1} - \mathbf{S}_n)/\Delta t$ -\State $\mathcal{L}_v\,\boldsymbol{\tau} \gets \mathbf{F}_{n+1}\,\dot{\mathbf{S}}\,\mathbf{F}_{n+1}^T$ -\Return $\mathcal{L}_v\,\boldsymbol{\tau}$ -\end{algorithmic} -$$ - -**Taichi Mapping:** -Use this construction to verify that the spatial rate $\dot{\boldsymbol{\tau}}-\mathbf{L}\boldsymbol{\tau}-\boldsymbol{\tau}\mathbf{L}^T$ matches the constructed Lie rate to round-off — a strong diagnostic for objective-rate kernels. In production prefer the spatial form (one matrix algebra rather than four pull-backs / push-forwards), but keep this routine as a unit test. - - - -## 4. Known Pitfalls -**Applying kinematic rule $\mathbf{F}^{-T}(\bullet)\mathbf{F}^{-1}$ to stress:** Stress is kinetic; using the kinematic rule on it (swapping $\mathbf{F}^{-T},\mathbf{F}^{-1}$ for $\mathbf{F},\mathbf{F}^T$) silently destroys $\boldsymbol{\tau}\colon\mathbf{D}=\mathbf{S}\colon\dot{\mathbf{E}}$ conjugacy and gives a numerically symmetric tensor that is the wrong stress. Symptom: integrated mechanical power in the global energy balance does not match the work of external loads. - - -**Wrong index order in $\mathbf{F}\mathbf{S}\mathbf{F}^T$:** $\tau_{ij}=F_{iI}F_{jJ}S_{IJ}$. Swapping to $F_{Ii}$ etc. (using $\mathbf{F}^T$ instead of $\mathbf{F}$) silently produces a transposed tangent that still has the right symmetries and passes minor consistency checks but is not $\boldsymbol{\tau}$. Always derive in indicial form and verify $\mathrm{tr}\,\boldsymbol{\tau}=J\,\mathrm{tr}\,\boldsymbol{\sigma}$ on a uniaxial benchmark. - - -**Dropping the $J$ factor between $\boldsymbol{\sigma}$ and $\boldsymbol{\tau}$:** $\boldsymbol{\tau}=J\boldsymbol{\sigma}$, NOT $\boldsymbol{\tau}=\boldsymbol{\sigma}$. The push-forward of $\mathbf{S}$ goes to $\boldsymbol{\tau}$, not to $\boldsymbol{\sigma}$ — recovering Cauchy requires an extra division by $J$. Forgetting the $J$ rescaling reports a stress wrong by $J$ on the deformed mesh (significant once $J\ne 1$). - - -**Push-forward of $\mathbf{S}$ is $\boldsymbol{\tau}$ not $\boldsymbol{\sigma}$:** A common slip: writing "push-forward of PK2 = Cauchy" instead of "= Kirchhoff". The composition $\boldsymbol{\sigma}=J^{-1}\mathbf{F}\mathbf{S}\mathbf{F}^T$ is the push-forward followed by Kirchhoff-to-Cauchy rescaling — TWO operations. Treating it as a single push-forward formula causes the $J^{-1}$ factor to be absorbed elsewhere by mistake. - - -**Round-off skew in $\boldsymbol{\tau}$ from non-symmetric $\mathbf{F}\mathbf{S}\mathbf{F}^T$:** Even with $\mathbf{S}$ exactly symmetric, $\mathbf{F}\mathbf{S}\mathbf{F}^T$ in floating-point introduces $\mathcal{O}(10^{-14})$ skew. Symmetrise $\boldsymbol{\tau}\to\tfrac12(\boldsymbol{\tau}+\boldsymbol{\tau}^T)$ before storing; otherwise the skew accumulates over many Newton iterations and breaks angular-momentum balance. - - -**Naive Voigt $6\times 6$ push-forward:** $\boldsymbol{\tau}=\mathbf{F}\mathbf{S}\mathbf{F}^T$ in Voigt form is NOT $\{F\}_{6\times 6}\{S\}_{6\times 1}$ — the two-point structure of $\mathbf{F}$ does not survive the symmetric flatten. Either revert to indicial form for the push-forward or build a specialised $6\times 6$ kinetic-Voigt operator $\mathbf{T}_\sigma(\mathbf{F})$ that respects the kinetic rule. See `tensor-voigt-notation` pitfalls for details. - - -**Using $\dot{\boldsymbol{\tau}}$ in a constitutive law:** $\dot{\boldsymbol{\tau}}$ is NOT objective: under a rigid-body rotation it picks up $\mathbf{L}\boldsymbol{\tau}+\boldsymbol{\tau}\mathbf{L}^T$ contributions. Constitutive laws must use $\mathcal{L}_v\boldsymbol{\tau}=\dot{\boldsymbol{\tau}}-\mathbf{L}\boldsymbol{\tau}-\boldsymbol{\tau}\mathbf{L}^T$ (the convected / Truesdell rate). Substituting $\dot{\boldsymbol{\tau}}$ produces oscillating shear stress under simple shear (`kinematics-objective-rates`). - - -## 5. References -- Belytschko, Liu, Moran & Elkhodary (2014) — Nonlinear Finite Elements for Continua and Structures, 2nd ed. (push-forward / pull-back of stress, Piola transformation, conjugacy of $\boldsymbol{\tau}\colon\mathbf{D}=\mathbf{S}\colon\dot{\mathbf{E}}$) -- Holzapfel (2000) — Nonlinear Solid Mechanics (kinetic vs kinematic push-forward, Lie derivative, convected rate) -- de Borst, Crisfield, Remmers & Verhoosel (2012) — Nonlinear Finite Element Analysis of Solids and Structures, 2nd ed. (Piola transformation in TL / UL FEM) - diff --git a/packages/akms/src/akms/_bundled/global_nodes/stress-tangent-push-forward.md b/packages/akms/src/akms/_bundled/global_nodes/stress-tangent-push-forward.md deleted file mode 100644 index 3822124..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/stress-tangent-push-forward.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: stress-tangent-push-forward -title: Push-Forward of 4th-Order Tangent -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- continuum-mechanics -- tangent-moduli -- fourth-order -status: established -confidence: 0.9 -source: hybrid -edges: -- to: stress-push-forward-pull-back - type: requires - weight: 1.0 -- to: tensor-derivatives-tensors - type: requires - weight: 1.0 -- to: tensor-voigt-notation - type: requires - weight: 0.7 -- to: kinematics-objective-rates - type: feeds-into - weight: 1.0 -- to: plasticity-consistent-tangent-general - type: feeds-into - weight: 1.0 -- to: fem-tl-linearization - type: feeds-into - weight: 0.9 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Push-Forward of 4th-Order Tangent - -## Summary - -The push-forward of a fourth-order material tangent modulus tensor maps Second Piola-Kirchhoff constitutive relations from reference material space to spatial Eulerian coordinate frames. This transformation contracts four legs of the deformation gradient tensor with the material tangent tensor, scaling by the Jacobian determinant to yield consistent spatial Kirchhoff or Cauchy stress tangent tensors for non-linear finite element linearizations. - -## 1. Core Concept - -In finite-strain solid mechanics, rate-type constitutive updates and Newton-Raphson tangent stiffness matrices require converting material constitutive tensors defined in the reference domain (such as \(C^{SE}_{mnpq} = \partial S_{mn} / \partial E_{pq}\)) into spatial tangent tensors defined in the current configuration. The push-forward transformation \(\phi_*\) maps each index of the fourth-order material tensor through the deformation gradient tensor \(F\). Pushing forward \(C^{SE}\) yields the fourth-order spatial Kirchhoff tangent tensor \(C^{\tau}_{ijkl} = F_{im} F_{jn} F_{kp} F_{lq} C^{SE}_{mnpq}\). Dividing by the volume Jacobian \(J = \det F\) delivers the Truesdell Cauchy stress tangent tensor \(C^{\sigma T}_{ijkl}\), which can be adjusted via stress-dependent terms to yield spatial tangent tensors corresponding to Jaumann or Green-Naghdi objective stress rates. - -## 2. Mathematical Formulation - -**Push-Forward of Fourth-Order Material Tangent to Kirchhoff Tangent** -$$ -C^{\tau}_{ijkl} = F_{im} F_{jn} F_{kp} F_{lq} C^{SE}_{mnpq} -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 5.16 & Eq. 5.10.44, pp. 315–316; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Sec. 4.5 & Box 3, pp. 5389–5390_ - -**Cauchy Stress Truesdell Spatial Tangent Modulus** -$$ -C^{\sigma T}_{ijkl} = \frac{1}{J} C^{\tau}_{ijkl} = \frac{1}{J} F_{im} F_{jn} F_{kp} F_{lq} C^{SE}_{mnpq} -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 5.1, p. 245 & Box 6.5, p. 364; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.1, Eq. 12.19, pp. 403–404_ - -**Geometric Push-Forward Operator Duality** -$$ -\mathcal{H} = \phi_* C^{SE}, \quad \mathcal{H}_{ijkl} = F_{im} F_{jn} F_{kp} F_{lq} C^{SE}_{mnpq} -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 5.10.2, Eqs. 5.10.43–5.10.44, p. 316; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.3, p. 37_ - -**Conversion Between Truesdell and Jaumann Spatial Tangents** -$$ -C^{\sigma J}_{ijkl} = C^{\sigma T}_{ijkl} + \frac{1}{2}(\sigma_{ik} \delta_{jl} + \sigma_{il} \delta_{jk} + \delta_{ik} \sigma_{jl} + \delta_{il} \sigma_{jk}) -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 5.1, p. 245; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.1, Eq. 12.22 & Sec. 12.3, p. 412_ - -**Notation:** -{'C^{SE}_{mnpq}': 'Fourth-order material tangent constitutive tensor in reference domain.', 'C^{\\tau}_{ijkl}': 'Fourth-order Kirchhoff spatial tangent modulus tensor.', 'C^{\\sigma T}_{ijkl}': 'Fourth-order spatial tangent tensor for Truesdell rate of Cauchy stress.', 'C^{\\sigma J}_{ijkl}': 'Fourth-order spatial tangent tensor for Jaumann rate of Cauchy stress.', 'F_{im}': 'Deformation gradient tensor component mapping reference to spatial coordinates.', 'J': 'Jacobian determinant J = det F.', '\\sigma_{ij}': 'Cauchy stress tensor component.', '\\delta_{ij}': 'Kronecker delta identity tensor.'} - - -## 3. Algorithmic Implementation - -**Fourth-Order Tangent Modulus Push-Forward Computation Algorithm** -$$ -\begin{algorithmic} -\State $Given 4th-order material tangent C^{SE}_{mnpq}, deformation gradient F_{ij}, and Jacobian J = \det F$ -\For{$i \gets 1 \text{ to } 3$} -\For{$j \gets 1 \text{ to } 3$} -\For{$k \gets 1 \text{ to } 3$} -\For{$l \gets 1 \text{ to } 3$} -\State $Evaluate Kirchhoff tangent component C^{\tau}_{ijkl} \gets \sum_{m=1}^3 \sum_{n=1}^3 \sum_{p=1}^3 \sum_{q=1}^3 F_{im} F_{jn} F_{kp} F_{lq} C^{SE}_{mnpq}$ -\State $Evaluate Truesdell Cauchy tangent component C^{\sigma T}_{ijkl} \gets \frac{1}{J} C^{\tau}_{ijkl}$ -\EndFor -\EndFor -\EndFor -\EndFor -\Return $C^{\tau}, C^{\sigma T}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 5.1, p. 245 & Box 6.5, p. 364; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.1, pp. 403–404_ - - -## 4. Known Pitfalls - -- **Confusing Spatial Tangent Moduli across Different Objective Rates**: Applying a material tangent C^{SE} or Truesdell spatial tangent C^{\sigma T} directly in a finite element formulation that uses the Jaumann rate causes inconsistent linearization and loss of quadratic Newton convergence. Mitigation: Transform tangent moduli using exact rate-conversion relations, such as C^{\sigma J}_{ijkl} = C^{\sigma T}_{ijkl} + \frac{1}{2}(\sigma_{ik}\delta_{jl} + \sigma_{il}\delta_{jk} + \delta_{ik}\sigma_{jl} + \delta_{il}\sigma_{jk}). _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 5.1, p. 245 & Box 6.6, p. 375; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.1, Eq. 12.22, p. 406)_ -- **Omitting Geometric Stiffness Terms During Linearization**: Using only the pushed-forward material tangent K^{\mathrm{mat}} in Updated or Total Lagrangian Newton-Raphson solvers while ignoring initial-stress geometric stiffness terms K^{\mathrm{geo}} = \mathbf{I} \int_{\Omega} \mathbf{B}_I^T \boldsymbol{\sigma} \mathbf{B}_J \, \mathrm{d}\Omega destroys quadratic convergence in finite strain analyses. Mitigation: Include both material stiffness K^{\mathrm{mat}} and geometric stiffness K^{\mathrm{geo}} when forming the global Jacobian matrix. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 6.5, p. 364; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 3.4.1, Eqs. 3.99–3.102, pp. 94–96)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-christoffel-symbols.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-christoffel-symbols.md deleted file mode 100644 index 341881a..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-christoffel-symbols.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -id: tensor-christoffel-symbols -title: Christoffel Symbols (1st and 2nd Kind) -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- curvilinear -- christoffel -- covariant-derivative -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-metric - type: requires - weight: 1.0 -- to: tensor-curvilinear-bases - type: requires - weight: 0.9 -- to: tensor-covariant-derivative - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Christoffel Symbols (1st and 2nd Kind) - -## Summary - -Christoffel symbols of the second kind (connection coefficients) characterize the metric-compatible, torsion-free Levi-Civita connection on a Riemannian manifold. Expressed in terms of metric tensor components and their spatial derivatives, they define covariant differentiation in curvilinear coordinates and transform non-tensorially under coordinate chart changes. - -## 1. Core Concept - -In tensor analysis on Riemannian manifolds, Christoffel symbols of the second kind \gamma^k_{ij} represent connection coefficients for the unique Levi-Civita connection \nabla. They express spatial derivatives of metric tensor components g_{ij} and quantify the geometric influence of curvilinear coordinate charts. Christoffel symbols are symmetric in their lower indices for torsion-free connections (\gamma^k_{ij} = \gamma^k_{ji}). Because their transformation law under coordinate chart changes contains an inhomogeneous second-derivative term, connection coefficients are not tensors. - -## 2. Mathematical Formulation - -**Christoffel Symbols of the Second Kind from Metric Tensor** -$$ -\gamma^k_{ij} = \frac{1}{2} g^{kl} \left( \frac{\partial g_{jl}}{\partial x^i} + \frac{\partial g_{il}}{\partial x^j} - \frac{\partial g_{ij}}{\partial x^l} \right) -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Theorem A.1, p. 39_ - -**Symmetry and Torsion-Free Property** -$$ -\gamma^k_{ij} = \gamma^k_{ji} -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Def. A.31, p. 39_ - -**Non-Tensorial Transformation Law Under Chart Transitions** -$$ -\gamma^j_{ki} = \frac{\partial x^{k'}}{\partial x^k} \frac{\partial x^j}{\partial x^{j'}} \frac{\partial x^{i'}}{\partial x^i} \gamma^{j'}_{k' i'} + \frac{\partial x^j}{\partial x^{m'}} \frac{\partial^2 x^{m'}}{\partial x^k \partial x^i} -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Def. A.30, p. 39_ - -**Notation:** -{'g_{ij}': 'Components of the Riemannian metric tensor.', 'g^{kl}': 'Components of the inverse metric tensor satisfying g^{ik} g_{kj} = \\delta^i_j.', '\\gamma^k_{ij}': 'Christoffel symbols of the second kind (connection coefficients).', '\\nabla': 'Covariant derivative / Levi-Civita connection operator.'} - - -## 3. Algorithmic Implementation - -**Computation of Christoffel Symbols from Metric Tensor** -$$ -\begin{algorithmic} -\State $Given metric tensor components g_{ij}(x) and coordinate partial derivatives \frac{\partial g_{ij}}{\partial x^k}$ -\State $Compute inverse metric tensor g^{kl} such that \sum_{k} g^{ik} g_{kj} = \delta^i_j$ -\For{$i \gets 1 \text{ to } n_{\mathrm{SD}}$} -\For{$j \gets 1 \text{ to } n_{\mathrm{SD}}$} -\For{$k \gets 1 \text{ to } n_{\mathrm{SD}}$} -\State $Evaluate \gamma^k_{ij} \gets \frac{1}{2} \sum_{l=1}^{n_{\mathrm{SD}}} g^{kl} \left( \frac{\partial g_{jl}}{\partial x^i} + \frac{\partial g_{il}}{\partial x^j} - \frac{\partial g_{ij}}{\partial x^l} \right)$ -\EndFor -\EndFor -\EndFor -\Return $\gamma^k_{ij}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Theorem A.1, p. 39_ - - -## 4. Known Pitfalls - -- **Treating Connection Coefficients as Tensor Components**: Attempting to transform Christoffel symbols \gamma^k_{ij} using standard multilinear tensor transformation laws. Connection coefficients pick up an inhomogeneous second-derivative term \frac{\partial x^j}{\partial x^{m'}} \frac{\partial^2 x^{m'}}{\partial x^k \partial x^i} under chart changes, reflecting coordinate frame curvature rather than intrinsic physical tensor transformation. _(Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Def. A.30 & Def. A.31, p. 39)_ -- **Assuming Lower-Index Symmetry in Torsion-Free Connections**: Applying lower-index symmetry \gamma^k_{ij} = \gamma^k_{ji} in non-holonomic frames or non-Riemannian connections with non-zero torsion. On Riemannian manifolds in coordinate charts, lower-index symmetry is uniquely guaranteed by the torsion-free Levi-Civita connection property. _(Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Def. A.31 & Theorem A.1, p. 39)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-covariant-derivative.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-covariant-derivative.md deleted file mode 100644 index f7b8d7d..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-covariant-derivative.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: tensor-covariant-derivative -title: Covariant Derivatives of Vectors & Tensors -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- curvilinear -- covariant-derivative -- divergence -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-christoffel-symbols - type: requires - weight: 1.0 -- to: tensor-metric - type: requires - weight: 0.9 -- to: kinematics-velocity-gradient - type: feeds-into - weight: 0.9 -- to: kinematics-objective-rates - type: feeds-into - weight: 0.8 -- to: fem-tl-weak-form - type: feeds-into - weight: 0.7 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Covariant Derivatives of Vectors & Tensors - -## Summary - -Covariant differentiation extends partial differentiation to curvilinear coordinate systems and Riemannian manifolds, accounting for spatially varying basis vectors through connection coefficients. Covariant derivatives transform as true tensors under coordinate chart changes, enabling frame-invariant formulations of continuum strain rates, velocity gradients, and field equations. - -## 1. Core Concept - -Standard partial derivatives of vector or tensor components fail to transform as tensors in non-Cartesian or curvilinear coordinate systems because base vectors vary from point to point. Covariant differentiation introduces connection coefficients \gamma^k_{ij} (Christoffel symbols of the second kind) to correct for base vector variations. For contravariant vector components v^i, the covariant derivative \nabla_j v^i combines partial derivatives with connection terms. For covariant 1-forms a_i, connection terms enter with a negative sign. The symmetric part of the spatial velocity covariant derivative \nabla v defines the rate of deformation tensor d_{ij} = \frac{1}{2}(\nabla_i v_j + \nabla_j v_i). - -## 2. Mathematical Formulation - -**Covariant Derivative of Contravariant Vector Components** -$$ -\nabla_j v^i = \frac{\partial v^i}{\partial x^j} + v^k \gamma^i_{kj} -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Def. A.30, p. 38_ - -**Covariant Derivative of Covariant 1-Form Components** -$$ -\nabla_j a_i = \frac{\partial a_i}{\partial x^j} - a_k \gamma^k_{ij} -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Def. A.30, p. 39_ - -**Covariant Derivative of Vector Along Vector Field** -$$ -\nabla_w v = \left( \frac{\partial v^i}{\partial x^j} w^j + v^k w^j \gamma^i_{kj} \right) \frac{\partial}{\partial x^i} -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Def. A.30, p. 39_ - -**Rate of Deformation Tensor in Covariant Form** -$$ -d_{ij} = \frac{1}{2} (\nabla_i v_j + \nabla_j v_i) -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Sec. 2.1, Prop. 2.8, p. 7_ - -**Notation:** -{'\\nabla': 'Covariant derivative operator.', 'v^i': 'Contravariant vector components.', 'a_i': 'Covariant 1-form components.', '\\gamma^k_{ij}': 'Connection coefficients (Christoffel symbols of the second kind).', 'd_{ij}': 'Components of the rate of deformation tensor d_\\flat.', 'w^j': 'Contravariant components of directional vector field w.'} - - -## 3. Algorithmic Implementation - -**Covariant Derivative and Rate of Deformation Computation Algorithm** -$$ -\begin{algorithmic} -\State $Given velocity vector components v^i(x), metric tensor g_{ij}(x), and connection coefficients \gamma^k_{ij}(x)$ -\State $Lower velocity indices to obtain covariant components v_i \gets g_{ij} v^j$ -\For{$i \gets 1 \text{ to } n_{\mathrm{SD}}$} -\For{$j \gets 1 \text{ to } n_{\mathrm{SD}}$} -\State $Compute contravariant vector covariant derivative \nabla_j v^i \gets \frac{\partial v^i}{\partial x^j} + \sum_{k=1}^{n_{\mathrm{SD}}} v^k \gamma^i_{kj}$ -\State $Compute 1-form covariant derivative \nabla_j v_i \gets \frac{\partial v_i}{\partial x^j} - \sum_{k=1}^{n_{\mathrm{SD}}} v_k \gamma^k_{ij}$ -\State $Evaluate rate of deformation tensor component d_{ij} \gets \frac{1}{2}(\nabla_i v_j + \nabla_j v_i)$ -\EndFor -\EndFor -\Return $\nabla v, d_{ij}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Sec. 2.1, Prop. 2.8, p. 7 & App. A.4, Def. A.30, pp. 38–39_ - - -## 4. Known Pitfalls - -- **Using Partial Differentiation in Curvilinear Coordinates**: Replacing covariant derivatives \nabla_j v^i with ordinary partial derivatives \partial v^i / \partial x^j in curvilinear coordinate systems omits connection coefficient terms \gamma^i_{kj} v^k, producing non-tensorial quantities that depend spuriously on coordinate chart choices. _(Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Def. A.30, pp. 38–39)_ -- **Applying Incorrect Sign on Connection Coefficients for Covariant vs Contravariant Indices**: Using a positive sign for connection terms when differentiating covariant 1-forms a_i (i.e., using +\gamma^k_{ij} a_k instead of -\gamma^k_{ij} a_k). Contravariant vector components use +\gamma^i_{kj} v^k, whereas covariant 1-form components require -\gamma^k_{ij} a_k. _(Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.4, Def. A.30, pp. 38–39)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Kolev_Desmorat_2021_Objective rates as covariant derivatives on the manifold of Riemannian metrics.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-curvilinear-bases.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-curvilinear-bases.md deleted file mode 100644 index d8e2c9f..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-curvilinear-bases.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -id: tensor-curvilinear-bases -title: Covariant & Contravariant Base Vectors -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- curvilinear -- convected-coordinates -- tensor-notation -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-index-notation - type: requires - weight: 0.9 -- to: tensor-metric - type: feeds-into - weight: 1.0 -- to: tensor-christoffel-symbols - type: feeds-into - weight: 0.9 -- to: kinematics-convected-coordinates - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Covariant & Contravariant Base Vectors - -## Summary - -Curvilinear coordinate systems establish local tangent and cotangent vector spaces spanned by covariant and contravariant base vectors. Covariant base vectors align with coordinate tangent lines, while dual contravariant base vectors satisfy reciprocal orthogonality. Metric tensor components perform index raising and lowering, enabling frame-invariant vector and tensor expansions in non-Cartesian domains. - -## 1. Core Concept - -In non-Cartesian curvilinear coordinate systems, basis vectors change direction and magnitude from point to point across the continuum domain. Covariant base vectors \mathbf{g}_i are defined as partial derivatives of spatial position with respect to curvilinear coordinates \theta^i. Contravariant base vectors \mathbf{g}^i span the dual cotangent space and satisfy the reciprocal duality relation \mathbf{g}_i \cdot \mathbf{g}^j = \delta_i^j. A vector v can be expressed either as a linear combination of contravariant components v^i with covariant base vectors \mathbf{g}_i, or covariant components v_i with contravariant base vectors \mathbf{g}^i. Metric tensor components g_{ij} = \mathbf{g}_i \cdot \mathbf{g}_j and inverse metric components g^{ij} = \mathbf{g}^i \cdot \mathbf{g}^j serve as fundamental operators for raising and lowering indices. - -## 2. Mathematical Formulation - -**Covariant Basis Vectors and Metric Tensor** -$$ -\mathbf{g}_i = \frac{\partial \mathbf{x}}{\partial \theta^i}, \quad g_{ij} = \mathbf{g}_i \cdot \mathbf{g}_j -$$ -_Source: Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.7 & 2.10.49, p. 1; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.2, Def. A.22, p. 36_ - -**Dual Basis Reciprocal Orthogonality** -$$ -\mathbf{g}_i \cdot \mathbf{g}^j = \delta_i^j -$$ -_Source: Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.49, p. 1; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.2, Def. A.22, p. 36_ - -**Vector Component Expansion in Dual Bases** -$$ -v = v^i \mathbf{g}_i = v_i \mathbf{g}^i, \quad v^i = v \cdot \mathbf{g}^i, \quad v_i = v \cdot \mathbf{g}_i -$$ -_Source: Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.49, p. 1; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.2, Def. A.22, p. 36_ - -**Tensor Component Index Raising and Lowering** -$$ -a_{ij} = g_{im} g_{jn} a^{mn}, \quad a^{ij} = g^{im} g^{jn} a_{mn} -$$ -_Source: Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf, Sec. 2.12, Eqs. 2.12.27 & 2.12.29–2.12.30, pp. 1–2_ - -**Notation:** -{'\\theta^i': 'Curvilinear coordinates.', '\\mathbf{g}_i': 'Covariant basis vector field.', '\\mathbf{g}^i': 'Dual contravariant basis vector field.', 'g_{ij}': 'Covariant metric tensor components.', 'g^{ij}': 'Contravariant inverse metric tensor components.', 'v^i': 'Contravariant vector components.', 'v_i': 'Covariant vector components.', '\\delta_i^j': 'Kronecker delta substitution tensor.'} - - -## 3. Algorithmic Implementation - -**Curvilinear Basis Vector and Component Transformation Algorithm** -$$ -\begin{algorithmic} -\State $Given spatial position x(\theta) in curvilinear coordinates \theta = (\theta^1, \theta^2, \theta^3) and vector components v^i$ -\State $Compute covariant basis vectors \mathbf{g}_i \gets \frac{\partial x}{\partial \theta^i} \text{ for } i \in \{1, 2, 3\}$ -\State $Compute covariant metric tensor components g_{ij} \gets \mathbf{g}_i \cdot \mathbf{g}_j$ -\State $Compute inverse metric matrix g^{ij} \gets (g_{ij})^{-1}$ -\State $Compute dual contravariant basis vectors \mathbf{g}^i \gets \sum_{j=1}^3 g^{ij} \mathbf{g}_j$ -\State $Lower vector component indices to covariant form v_i \gets \sum_{j=1}^3 g_{ij} v^j$ -\Return $\mathbf{g}_i, \mathbf{g}^i, g_{ij}, v_i$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.7 & 2.10.49, p. 1; Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf, Sec. 2.12, Eqs. 2.12.27–2.12.30, pp. 1–2_ - - -## 4. Known Pitfalls - -- **Mixing Covariant and Contravariant Basis Vector Transformations**: Confusing covariant base vectors \mathbf{g}_i = \partial \mathbf{x}/\partial \theta^i with contravariant base vectors \mathbf{g}^i = \mathrm{d}\theta^i. Covariant base vectors transform with partial derivatives of position, whereas contravariant base vectors transform with coordinate gradients, leading to inverse matrix relationships between basis transformations. _(Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.2, Def. A.22, p. 36; Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf, Sec. 2.12, pp. 1–2)_ -- **Direct Summation over Identical Index Positions**: Attempting to contract two upper indices (such as v^i w^i) or two lower indices (v_i w_i) directly in curvilinear coordinates without inserting the metric tensor g_{ij} or g^{ij}. Metric components must be introduced to raise or lower an index before evaluating inner products. _(Source: Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.49–2.10.50, p. 1; Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf, Sec. 2.12, Eqs. 2.12.27 & 2.12.30, pp. 1–2)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf -- Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-derivatives-scalars.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-derivatives-scalars.md deleted file mode 100644 index abc79be..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-derivatives-scalars.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: tensor-derivatives-scalars -title: Derivatives of Scalar Functions of Tensors -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- tensor-derivatives -- hyperelastic -- chain-rule -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-invariants - type: requires - weight: 1.0 -- to: tensor-products-contractions - type: requires - weight: 0.8 -- to: tensor-derivatives-tensors - type: feeds-into - weight: 0.9 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Derivatives of Scalar Functions of Tensors - -## Summary - -Derivatives of scalar-valued functions with respect to second-order tensors establish the foundation for hyperelastic constitutive modeling, stress evaluation, and non-linear finite element linearizations. Through tensor chain rules and primary invariant derivatives, scalar strain energy potentials generate symmetric stress tensors such as the Second Piola-Kirchhoff and Kirchhoff stress measures. - -## 1. Core Concept - -In non-linear continuum mechanics, hyperelastic material response is defined by a scalar strain energy density function W(C) or w(E). Differentiating this scalar potential with respect to the right Cauchy-Green deformation tensor C or Green-Lagrange strain tensor E yields energetically conjugate stress tensors: Second Piola-Kirchhoff stress S = 2 \partial W / \partial C = \partial w / \partial E. When energy potentials depend on deformation through primary scalar invariants I_1, I_2, I_3 or modified volumetric/isochoric invariants J_1, J_2, J_3, the derivative is evaluated by combining scalar partial derivatives with explicit tensor derivatives of the invariants (\partial I_1 / \partial C = I, \partial I_3 / \partial C = I_3 C^{-1}) via the tensor chain rule. - -## 2. Mathematical Formulation - -**Second Piola-Kirchhoff Stress as Scalar Potential Derivative** -$$ -S = 2 \frac{\partial W}{\partial C} = \frac{\partial w}{\partial E} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 11.4, Eq. 11.63, p. 376; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, p. 779_ - -**Derivatives of Primary Scalar Invariants** -$$ -\frac{\partial I_1}{\partial C} = I, \quad \frac{\partial I_2}{\partial C} = I_1 I - C, \quad \frac{\partial I_3}{\partial C} = I_3 C^{-1} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.1, p. 380_ - -**Tensor Chain Rule for Invariant-Based Potentials** -$$ -\frac{\partial W}{\partial C} = \sum_{k=1}^3 \frac{\partial W}{\partial J_k} \frac{\partial J_k}{\partial C} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.1, p. 380_ - -**Derivatives of Modified Isochoric and Volumetric Invariants** -$$ -\frac{\partial J_1}{\partial C} = I_3^{-1/3} \frac{\partial I_1}{\partial C} - \frac{1}{3} I_1 I_3^{-4/3} \frac{\partial I_3}{\partial C}, \quad \frac{\partial J_3}{\partial C} = \frac{1}{2} I_3^{-1/2} \frac{\partial I_3}{\partial C} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.1, p. 380_ - -**Notation:** -{'W': 'Scalar strain energy density function.', 'C': 'Symmetric right Cauchy-Green deformation tensor C = F^T F.', 'S': 'Second Piola-Kirchhoff stress tensor.', 'I_1, I_2, I_3': 'Primary scalar invariants of tensor C.', 'J_1, J_2, J_3': 'Modified volumetric/isochoric invariants.', 'I': 'Second-order identity tensor.'} - - -## 3. Algorithmic Implementation - -**Hyperelastic Stress Evaluation via Scalar Tensor Differentiation** -$$ -\begin{algorithmic} -\State $Given right Cauchy-Green tensor C and hyperelastic energy potential W(J_1, J_2, J_3)$ -\State $Compute primary invariants I_1 \gets \mathrm{tr}(C), I_2 \gets \frac{1}{2}[(\mathrm{tr} C)^2 - \mathrm{tr}(C^2)], I_3 \gets \det(C)$ -\State $Compute modified invariants J_1 \gets I_1 I_3^{-1/3}, J_2 \gets I_2 I_3^{-2/3}, J_3 \gets I_3^{1/2}$ -\State $Compute primary invariant derivatives \frac{\partial I_1}{\partial C} \gets I, \quad \frac{\partial I_2}{\partial C} \gets I_1 I - C, \quad \frac{\partial I_3}{\partial C} \gets I_3 C^{-1}$ -\State $Compute modified invariant derivatives \frac{\partial J_k}{\partial C} \text{ for } k \in \{1, 2, 3\}$ -\State $Evaluate partial scalar derivatives \frac{\partial W}{\partial J_k}$ -\State $Assemble Second Piola-Kirchhoff stress tensor S \gets 2 \sum_{k=1}^3 \frac{\partial W}{\partial J_k} \frac{\partial J_k}{\partial C}$ -\Return $S$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.1, p. 380_ - - -## 4. Known Pitfalls - -- **Omitting Symmetry in Differentiation of Symmetric Tensors**: Differentiating scalar functions of symmetric tensors (such as C or E) without accounting for symmetry constraints can lead to non-symmetric stress tensor outputs or incorrect off-diagonal factor scaling. Mitigation: Enforce symmetry on scalar tensor derivatives by evaluating symmetric projections \frac{1}{2}\left(\frac{\partial W}{\partial C} + \left(\frac{\partial W}{\partial C}\right)^T\right). _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.1, p. 380 & Box 11.2, p. 381)_ -- **Singular Inverse Invariants at Zero Determinant**: Evaluating derivative expressions involving \frac{\partial I_3}{\partial C} = I_3 C^{-1} or \frac{\partial J_1}{\partial C} when \det C \to 0 causes division-by-zero singularities. Mitigation: Use adjugate matrix formulations or check for non-singular deformation states (\det F > 0) prior to invariant differentiation. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.1, p. 380)_ - -## References - -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-derivatives-tensors.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-derivatives-tensors.md deleted file mode 100644 index 804ce8c..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-derivatives-tensors.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: tensor-derivatives-tensors -title: Derivatives of Tensors w.r.t. Tensors -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- tensor-derivatives -- fourth-order -- carlson-hoger -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-derivatives-scalars - type: requires - weight: 1.0 -- to: tensor-products-contractions - type: requires - weight: 1.0 -- to: tensor-spectral-decomposition - type: feeds-into - weight: 1.0 -- to: tensor-isotropic-functions - type: feeds-into - weight: 1.0 -- to: plasticity-consistent-tangent-general - type: feeds-into - weight: 0.9 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Derivatives of Tensors w.r.t. Tensors - -## Summary - -Derivatives of second-order tensors with respect to second-order tensors yield fourth-order linear transformation tensors. These fourth-order derivatives form the foundation for algorithmic consistent tangent operators, elastic-plastic tangent moduli, kinematic strain-gradient transformations, and inverse tensor differentials in non-linear finite element formulations. - -## 1. Core Concept - -In finite-strain solid mechanics, linearizing non-linear constitutive relations or kinematic transformations requires differentiating second-order tensor fields (such as stress, logarithmic strain, or stretch) with respect to state tensors (such as deformation gradients, Cauchy-Green tensors, or left stretch tensors). The resulting derivative is a fourth-order tensor mapping second-order tensor increments to second-order tensor variations. Key analytical identities include the derivative of inverse tensor fields \mathrm{d}\mathbf{C}^{-1} = -\mathbf{C}^{-1} \mathrm{d}\mathbf{C} \mathbf{C}^{-1}, the derivative of elastic Green-Lagrange strain \frac{\partial \mathbf{E}^e}{\partial \mathbf{F}^e} = \frac{1}{2}(\mathbf{I} \bar{\otimes} \mathbf{F}^{eT} + \mathbf{F}^{eT} \otimes \mathbf{I}), and the fourth-order derivative of squared symmetric tensors. These tensor-by-tensor derivative operators enable implicit return mapping linearizations and exact Newton-Raphson global convergence. - -## 2. Mathematical Formulation - -**Inverse Tensor Differential Identity** -$$ -\mathrm{d}\mathbf{C}^{-1} = -\mathbf{C}^{-1} \mathrm{d}\mathbf{C} \mathbf{C}^{-1} -$$ -_Source: Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf, Sec. III-E, p. 6_ - -**Elastic Strain Derivative with Respect to Deformation Gradient** -$$ -\frac{\partial \mathbf{E}^e}{\partial \mathbf{F}^e} = \frac{1}{2} \left( \mathbf{I} \bar{\otimes} \mathbf{F}^{eT} + \mathbf{F}^{eT} \otimes \mathbf{I} \right) -$$ -_Source: Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, Eq. A.21, p. 50_ - -**Fourth-Order Derivative of Squared Symmetric Tensor** -$$ -\left( \frac{\mathrm{d}\tilde{\mathbf{C}}^2}{\mathrm{d}\tilde{\mathbf{C}}} \right)_{ijkl} = \frac{1}{2} \left( \delta_{ik}\tilde{\mathbf{C}}_{lj} + \delta_{il}\tilde{\mathbf{C}}_{kj} + \delta_{jl}\tilde{\mathbf{C}}_{ik} + \delta_{kj}\tilde{\mathbf{C}}_{il} \right) -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.3, p. 387_ - -**Left Stretch Tensor Derivative in Updated Kinematics** -$$ -\left[ \frac{\partial \mathbf{B}_e^e}{\partial \mathbf{F}_{j+1}} \right]_{ijkl} = \delta_{ik}(\mathbf{B}_e^e)_{jl} + \delta_{jk}(\mathbf{B}_e^e)_{il} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.5, Eq. 12.114, p. 422_ - -**Notation:** -{'\\mathbf{F}^e': 'Elastic deformation gradient tensor.', '\\mathbf{E}^e': 'Elastic Green-Lagrange strain tensor.', '\\mathbf{C}': 'Right Cauchy-Green deformation tensor.', '\\mathbf{B}_e^e': 'Elastic left Cauchy-Green deformation tensor.', '\\boldsymbol{\\varepsilon}_e^e': 'Logarithmic strain tensor \\boldsymbol{\\varepsilon}_e^e = \\frac{1}{2}\\ln \\mathbf{B}_e^e.', '\\delta_{ij}': 'Kronecker delta identity component.'} - - -## 3. Algorithmic Implementation - -**Fourth-Order Logarithmic Strain-Tensor Derivative Algorithm** -$$ -\begin{algorithmic} -\State $Given elastic left Cauchy-Green tensor \mathbf{B}_e^e and updated deformation gradient \mathbf{F}_{j+1}$ -\State $Compute spectral decomposition of \mathbf{B}_e^e to find principal stretches \lambda_i^2 and spatial eigenprojections \mathbf{E}_i$ -\State $Evaluate logarithmic strain tensor \boldsymbol{\varepsilon}_e^e \gets \frac{1}{2} \ln \mathbf{B}_e^e = \sum_{i=1}^3 (\ln \lambda_i) \mathbf{E}_i$ -\State $Evaluate fourth-order tensor derivative \frac{\partial \boldsymbol{\varepsilon}_e^e}{\partial \mathbf{B}_e^e} \gets \frac{1}{2} \frac{\partial \ln[\mathbf{B}_e^e]}{\partial \mathbf{B}_e^e}$ -\State $Evaluate kinematic gradient derivative \left[\frac{\partial \mathbf{B}_e^e}{\partial \mathbf{F}_{j+1}}\right]_{ijkl} \gets \delta_{ik}(\mathbf{B}_e^e)_{jl} + \delta_{jk}(\mathbf{B}_e^e)_{il}$ -\State $Compose total fourth-order chain rule tangent \frac{\partial \boldsymbol{\varepsilon}_e^e}{\partial \mathbf{F}_{j+1}} \gets \frac{\partial \boldsymbol{\varepsilon}_e^e}{\partial \mathbf{B}_e^e} : \frac{\partial \mathbf{B}_e^e}{\partial \mathbf{F}_{j+1}}$ -\Return $\frac{\partial \boldsymbol{\varepsilon}_e^e}{\partial \mathbf{F}_{j+1}}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 12.5, Eqs. 12.111–12.114, pp. 421–422_ - - -## 4. Known Pitfalls - -- **Ignoring Major and Minor Symmetries in Fourth-Order Derivatives**: Assuming arbitrary fourth-order tensor derivatives possess major symmetry (\mathbb{C}_{ijkl} = \mathbb{C}_{klij}) or minor symmetries (\mathbb{C}_{ijkl} = \mathbb{C}_{jikl} = \mathbb{C}_{ijlk}). Differentiating non-symmetric second-order tensors or non-associated potential functions breaks major symmetry, resulting in non-symmetric global tangent stiffness matrices. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 7.7, p. 252 & Sec. 12.1, p. 406)_ -- **Failure to Apply Chain Rule Across Non-Coaxial Intermediate Configurations**: Differentiating composite stress functions without accounting for rotations between intermediate elastic-plastic configurations or principal axis rotations introduces kinematic inconsistency and destroys quadratic Newton convergence. Mitigation: Apply exact multi-stage fourth-order tensor chain rule contractions \frac{\partial \mathbf{M}}{\partial \mathbf{F}^e} = \frac{\partial \mathbf{M}}{\partial \mathbf{\Pi}^e} : \frac{\partial \mathbf{\Pi}^e}{\partial \mathbf{E}^e} : \frac{\partial \mathbf{E}^e}{\partial \mathbf{F}^e}. _(Source: Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, Eq. A.21, p. 50; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Sec. 2.6 & Box 3, pp. 5389, 5406)_ - -## References - -- Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Brown et al_2022_Performance Portable Solid Mechanics via Matrix-Free \\(p\\)-Multigrid.pdf -- Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf -- Rashid - 1993 - Incremental kinematics for finite element applications.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-index-notation.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-index-notation.md deleted file mode 100644 index 3c00e64..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-index-notation.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -id: tensor-index-notation -title: Index Notation & Einstein Convention -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- index-notation -- einstein-convention -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-products-contractions - type: feeds-into - weight: 1.0 -- to: tensor-invariants - type: feeds-into - weight: 0.9 -- to: kinematics-motion-deformation-gradient - type: feeds-into - weight: 0.8 -- to: fem-tl-b-matrix - type: feeds-into - weight: 0.7 -context_size: small -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Index Notation & Einstein Convention - -## Summary - -Index notation and the Einstein summation convention provide a concise indicial framework for representing vector and tensor operations in continuum mechanics. By implicitly summing over repeated indices and utilizing index operators like the Kronecker delta and Levi-Civita permutation symbol, index notation expresses complex tensor contractions, gradients, and balance equations in component form. - -## 1. Core Concept - -Index notation replaces direct tensor operators with component expressions referred to Cartesian or curvilinear coordinate bases. Under the Einstein summation convention, any index appearing twice in a single term implies a summation over spatial dimensions (typically 1, 2, 3). Free indices appear once per term and dictate the tensorial rank of the resulting expression. The Kronecker delta \delta_{ij} acts as an identity operator and index substitution tool, while the Levi-Civita permutation symbol e_{ijk} expresses cross products and determinants. Spatial partial differentiation is denoted compactly using comma notation (a_{i,j} = \partial a_i / \partial x_j). - -## 2. Mathematical Formulation - -**Einstein Summation and Tensor Contraction** -$$ -c = a \cdot b = a_i b_i, \quad (A \cdot B)_{ij} = A_{ik} B_{kj}, \quad A : B = A_{ij} B_{ij} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Notation & Sec. 1, pp. xv, 8, 22; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, pp. 777–778_ - -**Kronecker Delta Properties and Index Substitution** -$$ -\delta_{ij} = \begin{cases} 1 & \text{if } i = j \\ 0 & \text{if } i \neq j \end{cases}, \quad \delta_{ij} v_j = v_i, \quad \delta_{ij} A_{jk} = A_{ik}, \quad \delta_{ii} = 3 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Notation, p. xv; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, p. 778_ - -**Permutation Symbol and Cross Product** -$$ -(a \times b)_i = e_{ijk} a_j b_k, \quad e_{ijk} = \begin{cases} 1 & \text{if } (i,j,k) \in \{(1,2,3), (2,3,1), (3,1,2)\} \\ -1 & \text{if } (i,j,k) \in \{(1,3,2), (3,2,1), (2,1,3)\} \\ 0 & \text{otherwise} \end{cases} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Notation, p. xv; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, p. 778_ - -**Comma Derivative Notation** -$$ -f_{,i} = \frac{\partial f}{\partial x_i}, \quad v_{i,j} = \frac{\partial v_i}{\partial x_j}, \quad \sigma_{ij,j} = \frac{\partial \sigma_{ij}}{\partial x_j} -$$ -_Source: Bathe et al_1975_Finite element formulations for large deformation dynamic analysis.pdf, App. Nomenclature, p. 383; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 2.1, p. 32_ - -**Notation:** -{'\\delta_{ij}': 'Kronecker delta identity component.', 'e_{ijk}': 'Levi-Civita permutation symbol.', 'A_{ij}': 'Second-order tensor component.', 'C_{ijkl}': 'Fourth-order tensor component.', 'v_{i,j}': 'Partial derivative of vector component v_i with respect to coordinate x_j.'} - - -## 3. Algorithmic Implementation - -**Conversion of Direct Tensor Expressions to Index Notation and Matrix Form** -$$ -\begin{algorithmic} -\State $Given direct tensor expression for internal virtual work rate \dot{W}^{\mathrm{int}} = \int_V \boldsymbol{\sigma} : \mathbf{D} \, \mathrm{d}V$ -\State $Expand double contraction in index notation: \boldsymbol{\sigma} : \mathbf{D} \to \sigma_{ij} D_{ij}$ -\State $Apply symmetry of Cauchy stress \sigma_{ij} = \sigma_{ji} to write \sigma_{ij} D_{ij} = \sigma_{xx} D_{xx} + \sigma_{yy} D_{yy} + \sigma_{zz} D_{zz} + 2 \sigma_{xy} D_{xy} + 2 \sigma_{yz} D_{yz} + 2 \sigma_{zx} D_{zx}$ -\State $Map symmetric tensor components to Voigt vector arrays: \{\sigma\}^T = (\sigma_{xx}, \sigma_{yy}, \sigma_{zz}, \sigma_{xy}, \sigma_{yz}, \sigma_{zx}) \text{ and } \{\varepsilon\}^T = (\varepsilon_{xx}, \varepsilon_{yy}, \varepsilon_{zz}, 2\varepsilon_{xy}, 2\varepsilon_{yz}, 2\varepsilon_{zx})$ -\State $Re-evaluate inner product in vector form: \sigma_{ij} \varepsilon_{ij} = \{\sigma\}^T \{\varepsilon\}$ -\Return $\{\sigma\}^T \{\varepsilon\}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1, p. 22; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, pp. 777–778_ - - -## 4. Known Pitfalls - -- **Repeated Indices Beyond Dyadic Pair Limits**: Writing expressions where an index appears three or more times in a single term (such as A_{ii} B_{ij} v_i). Einstein summation is strictly defined for indices appearing exactly twice per term; three or more identical indices create ambiguous summation operations. Mitigation: Rename dummy indices or use explicit summation signs. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Notation & Sec. 1, pp. xv, 8; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, p. 778)_ -- **Mismatched Free Indices in Tensor Equations**: Inconsistent free index placement across terms in an equation (e.g. A_{ij} = B_{ik} C_{kj} + v_i), which violates tensorial rank consistency. Every term in a valid tensor equation must have identical unsummed free indices. Mitigation: Verify that free indices match in name and position across all terms. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Notation, p. xv; Bathe et al_1975_Finite element formulations for large deformation dynamic analysis.pdf, App. Nomenclature, p. 383)_ - -## References - -- Bathe et al_1975_Finite element formulations for large deformation dynamic analysis.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-invariants.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-invariants.md deleted file mode 100644 index 25e1911..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-invariants.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: tensor-invariants -title: Tensor Invariants ($I_1, I_2, I_3, J_2, J_3$) -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- invariants -- lode-angle -- cayley-hamilton -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-products-contractions - type: requires - weight: 0.9 -- to: tensor-derivatives-tensors - type: feeds-into - weight: 1.0 -- to: plasticity-von-mises - type: feeds-into - weight: 1.0 -- to: kinematics-strain-tensors - type: feeds-into - weight: 0.6 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Tensor Invariants ($I_1, I_2, I_3, J_2, J_3$) - -## Summary - -Tensor invariants are scalar quantities derived from second-order tensor fields that remain invariant under coordinate frame transformations. Primary invariants evaluate trace, double contraction, and determinant metrics, while deviatoric invariants quantify shear and distortion in constitutive modeling and yield surface formulations. - -## 1. Core Concept - -For any second-order tensor A, principal scalar invariants \(I_1, I_2, I_3\) characterize intrinsic geometric properties independent of coordinate basis choices. In continuum elasticity and hyperelasticity, the primary invariants of the right Cauchy-Green deformation tensor \(C\) govern strain energy density potentials. In continuum plasticity, the Cauchy stress tensor \(\boldsymbol{\sigma}\) is split into a hydrostatic pressure \(p = \frac{1}{3}\mathrm{tr}(\boldsymbol{\sigma})\) and a deviatoric stress tensor \(\mathbf{s} = \boldsymbol{\sigma} - p \mathbf{I}\). The second and third deviatoric stress invariants \(J_2 = \frac{1}{2}\mathrm{tr}(\mathbf{s}^2)\) and \(J_3 = \det(\mathbf{s})\) govern von Mises, Drucker-Prager, and Mohr-Coulomb yield criteria. The Lode angle parameterizes the stress state within the octahedral \(\pi\)-plane. - -## 2. Mathematical Formulation - -**Primary Invariants of Second-Order Tensor** -$$ -I_1 = \mathrm{tr}(A), \quad I_2 = \frac{1}{2} \left[ (\mathrm{tr} A)^2 - \mathrm{tr}(A^2) \right], \quad I_3 = \det(A) -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 5.2, p. 251; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 11.2, Eq. 11.40, p. 373_ - -**Characteristic Invariant Equation** -$$ -C_i^3 - I_1 C_i^2 + I_2 C_i - I_3 = 0 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 11.2, Eq. 11.39, p. 373; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Sec. 3.2, p. 5395_ - -**Deviatoric Stress Invariants J2 and J3** -$$ -J_2 = \frac{1}{2} \mathrm{tr}(\mathbf{s}^2) = \frac{1}{2} s_{ij} s_{ij}, \quad J_3 = \det(\mathbf{s}) = \frac{1}{3} \mathrm{tr}(\mathbf{s}^3) -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.3, p. 19 & Sec. 7.6, Eq. 7.169 & p. 262_ - -**Lode Angle Derivative Relation** -$$ -\frac{\partial \theta}{\partial \boldsymbol{\sigma}} = \frac{\sqrt{3}}{2 \cos 3\theta} \left( \frac{3}{2} J_2^{-5/2} J_3 \frac{\partial J_2}{\partial \boldsymbol{\sigma}} - J_2^{-3/2} \frac{\partial J_3}{\partial \boldsymbol{\sigma}} \right) -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 7.6, Eq. 7.169, p. 262_ - -**Notation:** -{'I_1, I_2, I_3': 'Principal scalar invariants of second-order tensor.', 'J_2, J_3': 'Second and third invariants of deviatoric stress tensor.', '\\mathbf{s}': 'Deviatoric stress tensor \\mathbf{s} = \\boldsymbol{\\sigma} - p \\mathbf{I}.', 'p': 'Hydrostatic pressure scalar p = \\frac{1}{3}\\mathrm{tr}(\\boldsymbol{\\sigma}).', '\\theta': 'Lode angle stress state parameter.'} - - -## 3. Algorithmic Implementation - -**Tensor Invariant and Deviatoric Invariant Evaluation Algorithm** -$$ -\begin{algorithmic} -\State $Given 3x3 symmetric tensor A (or Cauchy stress tensor \boldsymbol{\sigma})$ -\State $Compute trace I_1 \gets A_{11} + A_{22} + A_{33}$ -\State $Compute second invariant I_2 \gets A_{11}A_{22} + A_{22}A_{33} + A_{33}A_{11} - A_{12}^2 - A_{23}^2 - A_{31}^2$ -\State $Compute determinant I_3 \gets \det(A)$ -\State $Evaluate hydrostatic component p \gets \frac{1}{3} I_1 \text{ and deviatoric tensor } \mathbf{s} \gets A - p \mathbf{I}$ -\State $Compute second deviatoric invariant J_2 \gets \frac{1}{2}(s_{11}^2 + s_{22}^2 + s_{33}^2) + s_{12}^2 + s_{23}^2 + s_{31}^2$ -\State $Compute third deviatoric invariant J_3 \gets \det(\mathbf{s})$ -\Return $I_1, I_2, I_3, J_2, J_3$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.3, p. 19, Sec. 7.6, p. 262, & Box 5.2, p. 251_ - - -## 4. Known Pitfalls - -- **Assuming Invariance Under Non-Orthogonal Basis Transformations**: Evaluating tensor invariants using non-Cartesian or non-orthonormal components without incorporating metric tensor contractions. Invariants \\(I_1 = g^{ij} A_{ij}\\) and \\(I_2\\) require metric tensor \\(g^{ij}\\) in general curvilinear coordinate charts. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 5.2, p. 251; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Sec. 3, p. 19)_ -- **Lode Angle Indeterminacy at Hydrostatic and Shear Axis Singularities**: Evaluating Lode angle derivatives \partial \theta / \partial \boldsymbol{\sigma} when J_2 \to 0 or \cos 3\theta \to 0 causes division-by-zero singularities along the hydrostatic axis and corners of yield surfaces (such as Mohr-Coulomb or Tresca criteria). Mitigation: Use smoothed yield function representations or corner roundings. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 7.6, Eq. 7.169, p. 262)_ - -## References - -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-isotropic-functions.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-isotropic-functions.md deleted file mode 100644 index fc76e02..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-isotropic-functions.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: tensor-isotropic-functions -title: Isotropic Tensor Functions (exp, log, power) -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- isotropic-functions -- log-strain -- hencky-strain -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-spectral-decomposition - type: requires - weight: 1.0 -- to: tensor-derivatives-tensors - type: requires - weight: 1.0 -- to: kinematics-logarithmic-strain - type: feeds-into - weight: 1.0 -- to: kinematics-multiplicative-decomp - type: feeds-into - weight: 0.7 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Isotropic Tensor Functions (exp, log, power) - -## Summary - -Isotropic tensor functions evaluate scalar, vector, or tensor operations on second-order tensors independently of spatial coordinate rotations. Computed spectrally via eigenvalue-eigenprojection representations, isotropic functions define matrix exponentials, logarithms, and powers critical for logarithmic strain measures, hyperelastic strain energy potentials, and multiplicative elastic-plastic return-mapping updates. - -## 1. Core Concept - -An isotropic tensor function f(C) of a symmetric second-order tensor C commutes with arbitrary orthogonal rotation transformations, satisfying f(Q C Q^T) = Q f(C) Q^T. Using spectral decomposition, C is represented by its principal eigenvalues k_i and orthonormal eigenprojections E_i = N_i \otimes N_i. The isotropic function f(C) is evaluated by applying the scalar function f(\cdot) directly to eigenvalues k_i, giving f(C) = \sum_{i=1}^3 f(k_i) E_i. Key applications in finite deformation mechanics include evaluating logarithmic strain E = 1/2 \ln C, matrix exponential return mapping (F^e)^{t+\Delta t} = \exp((D^e)^{-1} : \kappa), and fractional stretch powers C^{1/2}. Computing fourth-order derivatives \partial f(C) / \partial C requires divided differences that handle distinct, double, and triple coalescent eigenvalues smoothly to prevent division-by-zero singularities. - -## 2. Mathematical Formulation - -**Spectral Evaluation of Isotropic Tensor Function** -$$ -f(C) = \sum_{i=1}^3 f(k_i) E_i, \quad E_i = N_i \otimes N_i -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.3, p. 387; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Box 3, p. 5406_ - -**Logarithmic Tensor Strain Evaluation** -$$ -E = \frac{1}{2} \ln C = \sum_{i=1}^3 \left( \frac{1}{2} \ln k_i \right) N_i \otimes N_i -$$ -_Source: Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Box 2 & Box 3, pp. 5391, 5406; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 11.8, Eq. 11.108, p. 388_ - -**Exponential Return-Mapping Tensor Update** -$$ -(F^e)^{t+\Delta t} = \exp \left( (D^e)^{-1} : \kappa^{n+1} \right) -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 12.2, p. 421_ - -**Fourth-Order Isotropic Derivative Coefficients via Divided Differences** -$$ -\theta_{ij} = \begin{cases} \frac{e_i - e_j}{k_i - k_j} & \text{if } k_i \neq k_j \\ \frac{1}{2 k_i} & \text{if } k_i = k_j \end{cases} -$$ -_Source: Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Box 3, p. 5406; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.3, p. 387_ - -**Notation:** -{'C': 'Symmetric positive-definite second-order tensor.', 'k_i': 'Principal eigenvalues of tensor C.', 'N_i': 'Orthonormal eigenvectors of tensor C.', 'E_i': 'Rank-one eigenprojection tensor E_i = N_i \\otimes N_i.', 'e_i': 'Scalar evaluation e_i = f(k_i) on principal eigenvalue k_i.', '\\theta_{ij}': 'Divided difference coefficient for fourth-order isotropic tensor derivatives.'} - - -## 3. Algorithmic Implementation - -**Spectral Evaluation and Differentiation of Isotropic Logarithmic Tensor Function** -$$ -\begin{algorithmic} -\State $Given symmetric positive-definite second-order tensor C$ -\State $Solve eigenvalue problem C N_i = k_i N_i to obtain principal eigenvalues k_i and orthonormal eigenvectors N_i for i \in \{1, 2, 3\}$ -\State $Evaluate scalar logarithmic function e_i \gets \frac{1}{2} \ln k_i \text{ and eigenprojections } E_i \gets N_i \otimes N_i$ -\State $Construct logarithmic strain tensor E \gets \sum_{i=1}^3 e_i E_i$ -\If{$Eigenvalues k_i are distinct (k_1 \neq k_2 \neq k_3)$} -\State $Compute divided difference coefficients \theta_{ij} \gets \frac{e_i - e_j}{k_i - k_j} \text{ for } i \neq j$ -\Else -\EndIf -\State $Assemble fourth-order isotropic derivative tensor \frac{\partial E}{\partial C}$ -\Return $E, \frac{\partial E}{\partial C}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Box 3, p. 5406; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.3, p. 387_ - - -## 4. Known Pitfalls - -- **Division-by-Zero Singularities at Coalescent Eigenvalues**: Evaluating fourth-order derivatives of isotropic tensor functions using raw finite difference formulas (k_i - k_j)^{-1} when two or three eigenvalues coalesce (k_i \approx k_j) causes severe floating-point division-by-zero errors. Mitigation: Use analytical limit expressions for equal eigenvalues (\theta_{ij} = \frac{1}{2 k_i}) or Taylor series expansions when |k_i - k_j| < \epsilon. _(Source: Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Box 3, p. 5406; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.3, p. 387)_ -- **Loss of Coaxiality in Anisotropic Constitutive Updates**: Assuming that isotropic tensor functions preserve diagonal spectral representations in anisotropic materials. While isotropic strain energy functions guarantee that stress S and Cauchy-Green tensor C share identical principal eigenprojections E_i, anisotropic structural tensors break coaxiality and require full tensor transformations. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.3, p. 387; Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf, Sec. 3.2, pp. 5393–5395)_ - -## References - -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Miehe et al. - 2002 - Anisotropic additive plasticity in the logarithmic strain space modular kinematic formulation and i.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-mandel-notation.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-mandel-notation.md deleted file mode 100644 index 6f4d4f9..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-mandel-notation.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: tensor-mandel-notation -title: Mandel Notation & Its Advantages -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- mandel -- kelvin-mandel -- tensor-notation -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-voigt-notation - type: refines - weight: 1.0 -- to: tensor-products-contractions - type: requires - weight: 0.8 -- to: tensor-spectral-decomposition - type: feeds-into - weight: 1.0 -context_size: small -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Mandel Notation & Its Advantages - -## Summary - -In finite-strain continuum mechanics and anisotropic plasticity, Mandel stress measures operate on Mandel's isoclinic intermediate configuration resulting from the multiplicative decomposition of the deformation gradient F = F^e F^p. Matrix-vector representations convert symmetric second-order stress and strain tensors and fourth-order tangent moduli into array forms for computational finite element assembly. - -## 1. Core Concept - -In non-linear continuum mechanics, constitutive formulations at finite deformations frequently employ Mandel's isoclinic intermediate configuration derived from the multiplicative decomposition F = F^e F^p. The Mandel stress tensor M = C^e S (or M_d) is defined on this intermediate configuration, driving inelastic flow rules and kinematic hardening. For computational implementation, second-order symmetric tensors and fourth-order tangent operators are mapped into matrix-vector formats to evaluate inner products, strain energy rates, and global element stiffness matrices. - -## 2. Mathematical Formulation - -**Mandel Stress Tensor in Intermediate Configuration** -$$ -M_d = 2 \rho_e C_{ps} \frac{\partial \psi_{\mathrm{kin}}}{\partial C_{ps}} -$$ -_Source: Generic_anisotropic_thermo-elastoviscoplasticity.pdf, Sec. 3, Eq. 35, p. 127; Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, p. 48_ - -**Multiplicative Plastic Velocity Gradient in Intermediate Frame** -$$ -\dot{F}^p (F^p)^{-1} = \dot{\lambda} \frac{\partial f}{\partial M_d} -$$ -_Source: Generic_anisotropic_thermo-elastoviscoplasticity.pdf, Sec. 3, Eq. 36, p. 127; Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, Eq. A.5, p. 48_ - -**Tensor Double Contraction and Matrix Vector Product** -$$ -\boldsymbol{\sigma} : \mathbf{D} = \sigma_{ij} D_{ij} = \{\sigma\}^T \{\varepsilon\} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1, p. 22; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, pp. 777–778_ - -**Notation:** -{'M_d': 'Mandel stress tensor on the isoclinic intermediate configuration.', 'F^e, F^p': 'Elastic and plastic parts of the multiplicative deformation gradient F = F^e F^p.', '\\boldsymbol{\\sigma}': 'Cauchy stress tensor.', '\\mathbf{D}': 'Rate of deformation tensor.', '\\{\\sigma\\}': 'Vector array representation of stress components.'} - - -## 3. Algorithmic Implementation - -**Evaluation of Mandel Stress and Inelastic Return Mapping in Intermediate Frame** -$$ -\begin{algorithmic} -\State $Given trial elastic deformation gradient F^e_0 and plastic deformation gradient F^p$ -\State $Compute intermediate configuration metric C_{ps} \gets F^{p-T}_d C^p F^{p-1}_d$ -\State $Evaluate Mandel stress tensor M_d \gets 2 \rho_e C_{ps} \frac{\partial \psi_{\mathrm{kin}}}{\partial C_{ps}}$ -\State $Evaluate yield function f(M_d, A_I, T) \text{ in intermediate frame}$ -\If{$f(M_d, A_I, T) > 0$} -\State $Compute plastic flow direction \frac{\partial f}{\partial M_d} \text{ and update } \dot{F}^p (F^p)^{-1} \gets \dot{\lambda} \frac{\partial f}{\partial M_d}$ -\EndIf -\Return $M_d, F^p$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Generic_anisotropic_thermo-elastoviscoplasticity.pdf, Sec. 3, Eqs. 34–36, p. 127; Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, Eqs. A.4–A.5, p. 48_ - - -## 4. Known Pitfalls - -- **Evaluating Plastic Flow Outside Mandel Isoclinic Intermediate Frame**: Computing plastic flow rules or yield functions using Cauchy stress in spatial coordinates without pulling back to Mandel's isoclinic intermediate configuration produces thermodynamically inconsistent plastic spin and artificial material anisotropy updates. Mitigation: Formulate inelastic evolution equations directly using Mandel stress M_d on the intermediate frame. _(Source: Generic_anisotropic_thermo-elastoviscoplasticity.pdf, Sec. 1 & Sec. 3, pp. 124, 127)_ -- **Mismatched Shear Factor Scalings in Matrix-Vector Tensor Contractions**: Mixing tensor double contractions \sigma_{ij} \varepsilon_{ij} with vector inner products without accounting for off-diagonal engineering shear factors (such as factor 2 in shear strains \gamma_{xy} = 2 \varepsilon_{xy}) corrupts energy calculations and stiffness matrix symmetry. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.3, p. 21; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, pp. 777–778)_ - -## References - -- Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Generic_anisotropic_thermo-elastoviscoplasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-metric.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-metric.md deleted file mode 100644 index fc197f6..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-metric.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: tensor-metric -title: Metric Tensor & Index Manipulation -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- curvilinear -- metric-tensor -- convected-coordinates -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-curvilinear-bases - type: requires - weight: 1.0 -- to: tensor-christoffel-symbols - type: feeds-into - weight: 1.0 -- to: kinematics-strain-tensors - type: feeds-into - weight: 1.0 -- to: kinematics-convected-coordinates - type: feeds-into - weight: 1.0 -context_size: small -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Metric Tensor & Index Manipulation - -## Summary - -The metric tensor defines inner products, line elements, and geometric volume measures on Riemannian manifolds and curvilinear coordinate systems. Its covariant coefficients g_{ij} and contravariant inverse coefficients g^{ij} serve as canonical index lowering and raising operators, establishing the foundation for convected kinematics and pull-back strain formulations. - -## 1. Core Concept - -The metric tensor g evaluates inner products between tangent vectors on a continuum manifold. In local curvilinear coordinates \theta^i, covariant metric components g_{ij} = \mathbf{g}_i \cdot \mathbf{g}_j evaluate squared differential line elements \mathrm{d}s^2 = \mathrm{d}\mathbf{x} \cdot \mathrm{d}\mathbf{x} = g_{ij} \mathrm{d}\theta^i \mathrm{d}\theta^j. Inverse metric components g^{ij} satisfy g_{ik} g^{kj} = \delta_i^j, forming the identity tensor operator I_M = \delta_i^j \mathrm{d}\theta^i \otimes \frac{\partial}{\partial \theta^j}. Metric coefficients act as index lowering (\flat) and raising (\sharp) operators on vector and tensor fields. In Euclidean Cartesian systems, the metric tensor simplifies to the identity tensor g = I. - -## 2. Mathematical Formulation - -**Covariant Metric Coefficients and Differential Line Element** -$$ -g_{ij} = \mathbf{g}_i \cdot \mathbf{g}_j = \left\langle \frac{\partial \mathbf{x}}{\partial \theta^i}, \frac{\partial \mathbf{x}}{\partial \theta^j} \right\rangle, \quad \mathrm{d}s^2 = g_{ij} \, \mathrm{d}\theta^i \, \mathrm{d}\theta^j -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.2, Def. A.14, p. 35; Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.9 & 2.10.50, p. 1_ - -**Inverse Metric Tensor and Identity Operator** -$$ -g_{ik} g^{kj} = \delta_i^j, \quad I_M = g \cdot g^{-1} = \delta_i^j \, \mathrm{d}\theta^i \otimes \frac{\partial}{\partial \theta^j} -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.2, Def. A.15, p. 35_ - -**Index Lowering and Raising Operators** -$$ -v_i = g_{ij} v^j, \quad v^i = g^{ij} v_j, \quad T_{ij} = g_{im} g_{jn} T^{mn} -$$ -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.2, Def. A.16 & Remark A.3, pp. 35–36; Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf, Sec. 2.12, Eqs. 2.12.27–2.12.30, pp. 1–2_ - -**Pull-Back Mapping of Spatial Metric to Cauchy-Green Tensor** -$$ -C = \phi^* g = F^T \cdot g \cdot F -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 5.16, p. 315 & Sec. 5.10, p. 316_ - -**Notation:** -{'g_{ij}': 'Covariant metric tensor components.', 'g^{ij}': 'Contravariant inverse metric tensor components.', '\\theta^i': 'Curvilinear or convected coordinates.', '\\delta_i^j': 'Kronecker delta identity tensor component.', 'v^i, v_i': 'Contravariant vector and covariant 1-form components.', '\\flat, \\sharp': 'Index lowering and index raising operators.'} - - -## 3. Algorithmic Implementation - -**Metric Tensor Evaluation and Index Manipulation Algorithm** -$$ -\begin{algorithmic} -\State $Given spatial position mapping x(\theta) in curvilinear coordinates \theta^i and contravariant vector v^i$ -\State $Compute covariant basis vectors \mathbf{g}_i \gets \frac{\partial x}{\partial \theta^i}$ -\State $Evaluate covariant metric components g_{ij} \gets \mathbf{g}_i \cdot \mathbf{g}_j$ -\State $Compute inverse matrix to obtain contravariant metric components g^{ij} \gets (g_{ij})^{-1}$ -\State $Apply index lowering operator v_i \gets \sum_{j=1}^3 g_{ij} v^j$ -\State $Verify inverse index raising v^i \gets \sum_{j=1}^3 g^{ij} v_j$ -\Return $g_{ij}, g^{ij}, v_i$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.2, Def. A.14–A.16, pp. 35–36; Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.9 & 2.10.50, p. 1_ - - -## 4. Known Pitfalls - -- **Confusing Covariant and Contravariant Metric Indices in Vector Products**: Evaluating inner products v \cdot w as \sum_i v^i w^i without inserting the metric tensor g_{ij}. In non-Cartesian curvilinear coordinate systems, the inner product requires metric contractions v \cdot w = g_{ij} v^i w^j = v^i w_i. _(Source: Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf, Eq. 2.10.49–2.10.50, p. 1; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A.2, Def. A.15, p. 35)_ -- **Assuming Spatial Metric g Is Variable in Flat Euclidean Space**: Failing to simplify g_{ij} = \delta_{ij} when operating in Cartesian coordinate frames. While general curvilinear systems require explicit metric calculations, Euclidean Cartesian frames satisfy g = I, reducing pull-back operations C = \phi^* g to C = F^T F. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 5.16 & Sec. 5.10, pp. 315–316)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Kinematics_of_CM_10_Convected_Coordinates.pdf.pdf -- Kinematics_of_CM_12_Pull_Back_Lie_Derivative.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-operations.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-operations.md deleted file mode 100644 index 3a72461..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-operations.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -id: tensor-operations -title: Push-Forward, Pull-Back & Tensor Transformations -domain: computational-mechanics -subdomain: kinematics -tags: -- kinematics -- finite-strain -- tensors -- continuum-mechanics -- push-forward -- pull-back -status: established -confidence: 0.9 -source: hybrid -confidence_floor: 0.7 -edges: -- to: kinematics-strain-tensors - type: feeds-into - weight: 1.0 - note: Provides transformation rules used to relate Lagrangian and Eulerian deformation measures (E vs e, C vs b) -- to: kinematics-objective-rates - type: feeds-into - weight: 0.9 - note: Lie derivative (= push-forward of d/dt of pull-back) is the mathematical basis for objective stress rates -- to: fem-tl-weak-form - type: feeds-into - weight: 0.8 - note: Total-Lagrangian FEM requires PK2<->Kirchhoff push-forward and tangent moduli transformation -context_size: medium -reading_priority: full -load_with: -- kinematics-strain-tensors -- kinematics-objective-rates -content_ref: null -akms_schema: v2 ---- - -# Push-Forward, Pull-Back & Tensor Transformations - -## Summary -Push-forward ($\phi_*$) and pull-back ($\phi^*$) are the fundamental operations that map tensor fields between the reference (Lagrangian) and current (Eulerian) configurations of a deforming body. They are driven by the deformation gradient $F$ and depend on the variance of the tensor: kinematic (covariant–covariant) tensors transform with $F^{-T}(\bullet)F^{-1}$ pushed forward and $F^T(\bullet)F$ pulled back, while kinetic (contravariant–contravariant) tensors transform with $F(\bullet)F^T$ pushed forward and $F^{-1}(\bullet)F^{-T}$ pulled back. The variance pairing is dictated by the requirement that the mechanical power $\boldsymbol{\sigma}\colon\mathbf{D}=\mathbf{S}\colon\dot{\mathbf{E}}$ remain invariant under the transformation. Push-forward of fourth-order tangent moduli applies $F$ index-by-index ($C^\tau_{ijkl}=F_{iM}F_{jN}F_{kP}F_{lQ}\,C^{SE}_{MNPQ}$), and the Lie derivative $\mathcal{L}_v = \phi_*(\partial_t \phi^*(\bullet))$ provides the mathematically consistent objective rate that underlies the convected/Truesdell stress rates. - - -## 1. Core Concept -In nonlinear continuum mechanics every field defined on the deformed body has a counterpart on the reference body and vice versa. Push-forward and pull-back give the precise algebraic prescription for transporting tensors of any order and variance between these two configurations using the two-point tensor $F = \partial\mathbf{x}/\partial\mathbf{X}$. - -The crucial subtlety is that the form of the transformation is not a free choice: it is dictated by the variance of the tensor (covariant indices "live downstairs", contravariant indices "live upstairs") and by the requirement that work-conjugate pairings be preserved. Stress-like (kinetic) objects such as the second Piola-Kirchhoff stress $\mathbf{S}$ and the Kirchhoff stress $\boldsymbol{\tau}$ are contravariant–contravariant; strain-like (kinematic) objects such as the Green strain rate $\dot{\mathbf{E}}$ and the rate-of-deformation $\mathbf{D}$ are covariant–covariant. Mixed objects such as the spatial velocity gradient $\mathbf{L}$ require mixed legs ($F^{-1}$ on the left, $F$ on the right). - -Because material time differentiation does not commute with push-forward, the Lie derivative is introduced as the mathematically consistent objective time derivative: pull a spatial tensor back, take its material rate, then push the result forward. This operation produces the Truesdell rate of Cauchy stress and the convected rate of Kirchhoff stress, which are the "natural" stress rates appearing in finite-strain hyperelasticity. - - -## 2. Mathematical Formulation -Let $\mathbf{X}$ denote a material point in the reference configuration $\Omega_0$ and $\mathbf{x}=\boldsymbol{\phi}(\mathbf{X},t)$ its position in the current configuration $\Omega_t$. The deformation gradient $\mathbf{F} = \partial\mathbf{x}/\partial\mathbf{X}$ is the two-point tensor that drives all transformations. Its determinant $J = \det\mathbf{F}$ is the local volume ratio, and the metric tensor in Euclidean space satisfies $\mathbf{g}=\mathbf{I}$. Push-forward and pull-back are denoted $\phi_*$ and $\phi^*$ respectively, and the rules below are the canonical Belytschko/Borst–Crisfield "Box 5.16" set. - - -**Vectors — push-forward / pull-back of line elements:** - -$$ -d\mathbf{x} = \phi_*(d\mathbf{X}) = \mathbf{F} \cdot d\mathbf{X}, \qquad -d\mathbf{X} = \phi^*(d\mathbf{x}) = \mathbf{F}^{-1} \cdot d\mathbf{x} -$$ - -where $d\mathbf{X}$ is a Lagrangian line element, $d\mathbf{x}$ its image in the current configuration - -**Volume transformation:** - -$$ -dV = J\,dV_0, \qquad J = \det \mathbf{F} = \frac{\rho_0}{\rho} -$$ - -where $dV_0$ and $dV$ are reference and current infinitesimal volumes; $\rho_0,\rho$ are reference and current densities - -**Nanson's formula — area / normals (covector transformation):** - -$$ -\mathbf{n}\,d\Gamma = J\,\mathbf{F}^{-T} \cdot \mathbf{n}_0\,d\Gamma_0 -$$ - -where $\mathbf{n}_0,d\Gamma_0$ are reference normal and area; $\mathbf{n},d\Gamma$ are their current counterparts - -**Kinematic (covariant–covariant) second-order tensors:** - -$$ -\phi_*(\bullet) = \mathbf{F}^{-T} \cdot (\bullet) \cdot \mathbf{F}^{-1}, \qquad -\phi^*(\bullet) = \mathbf{F}^T \cdot (\bullet) \cdot \mathbf{F} -$$ - -where Examples — $\mathbf{D} = \phi_*(\dot{\mathbf{E}}) = \mathbf{F}^{-T}\dot{\mathbf{E}}\mathbf{F}^{-1}$, $\dot{\mathbf{E}} = \phi^*(\mathbf{D}) = \mathbf{F}^T \mathbf{D}\, \mathbf{F}$, $\mathbf{C} = \phi^*(\mathbf{g})$ - -**Kinetic (contravariant–contravariant) second-order tensors:** - -$$ -\phi_*(\bullet) = \mathbf{F} \cdot (\bullet) \cdot \mathbf{F}^T, \qquad -\phi^*(\bullet) = \mathbf{F}^{-1} \cdot (\bullet) \cdot \mathbf{F}^{-T} -$$ - -where Examples — $\boldsymbol{\tau} = \phi_*(\mathbf{S}) = \mathbf{F}\mathbf{S}\mathbf{F}^T$, $\mathbf{S} = \phi^*(\boldsymbol{\tau}) = \mathbf{F}^{-1}\boldsymbol{\tau}\,\mathbf{F}^{-T}$ - -**Mixed (contravariant–covariant) tensors:** - -$$ -\phi^*(\mathbf{L}) = \mathbf{F}^{-1} \cdot \mathbf{L} \cdot \mathbf{F}, \qquad -\phi_*(\widetilde{\mathbf{L}}) = \mathbf{F} \cdot \widetilde{\mathbf{L}} \cdot \mathbf{F}^{-1} -$$ - -where $\mathbf{L} = \dot{\mathbf{F}}\mathbf{F}^{-1}$ is the spatial velocity gradient; $\mathbf{F}^{-1}$ acts on the contravariant (left) leg, $\mathbf{F}$ on the covariant (right) leg - -**Push-forward of fourth-order elasticity tensor (index-by-index):** - -$$ -C^{\tau}_{ijkl} = F_{iM}\,F_{jN}\,F_{kP}\,F_{lQ}\,C^{SE}_{MNPQ} -$$ - -where $C^{SE}_{MNPQ}$ are material tangent moduli (a.k.a. $A^{(2)}$); $C^{\tau}_{ijkl}$ are spatial tangent moduli (a.k.a. $A^{(4)}$). Lower-case indices are spatial, upper-case material; summation convention applies - -**Lie derivative — mathematically consistent objective rate:** - -$$ -\mathcal{L}_v(\bullet) = \phi_*\!\left(\frac{D}{Dt}\,\phi^*(\bullet)\right) -$$ - -where $D/Dt$ is the material time derivative (holding $\mathbf{X}$ fixed); $\mathcal{L}_v$ commutes with push-forward by construction - -**Lie derivative of Kirchhoff stress = convected / Truesdell rate:** - -$$ -\mathcal{L}_v\boldsymbol{\tau} = \mathbf{F} \cdot \dot{\mathbf{S}} \cdot \mathbf{F}^T -= \dot{\boldsymbol{\tau}} - \mathbf{L}\cdot\boldsymbol{\tau} - \boldsymbol{\tau}\cdot\mathbf{L}^T -\equiv \boldsymbol{\tau}^{\nabla c} -$$ - -where $\dot{\boldsymbol{\tau}}$ is non-objective; subtraction of $\mathbf{L}\boldsymbol{\tau}+\boldsymbol{\tau}\mathbf{L}^T$ removes spurious rotation/stretch contributions - -**Lie derivative of spatial metric:** - -$$ -\mathcal{L}_v\,\mathbf{g} = \mathbf{F}^{-T}\cdot\dot{\mathbf{C}}\cdot\mathbf{F}^{-1} = 2\mathbf{D} -$$ - -where Recovers the rate-of-deformation as the kinematic Lie derivative of the metric - -**Power conjugacy invariance (motivates the variance rules):** - -$$ -\boldsymbol{\tau} \colon \mathbf{D} -= \big(\mathbf{F}\mathbf{S}\mathbf{F}^T\big) \colon \big(\mathbf{F}^{-T}\dot{\mathbf{E}}\mathbf{F}^{-1}\big) -= \mathbf{S} \colon \dot{\mathbf{E}} -$$ - -where Confirms that the kinetic / kinematic pairing is the unique choice preserving stress-power - -**Notation:** - -- $\mathbf{F}$ — Deformation gradient, two-point tensor with $F_{iI} = \partial x_i/\partial X_I$ -- $\mathbf{F}^T$ — Transpose of $\mathbf{F}$ -- $\mathbf{F}^{-1}$ — Inverse of $\mathbf{F}$ -- $\mathbf{F}^{-T}$ — Inverse transpose, $(\mathbf{F}^{-1})^T$ -- $J$ — Jacobian determinant, $J=\det\mathbf{F}$, equals the volume ratio $dV/dV_0$ -- $\phi_*$ — Push-forward operator (reference $\to$ current configuration) -- $\phi^*$ — Pull-back operator (current $\to$ reference configuration) -- $\mathbf{S}$ — Second Piola-Kirchhoff stress (Lagrangian, kinetic) -- $\boldsymbol{\tau}$ — Kirchhoff stress, $\boldsymbol{\tau}=J\boldsymbol{\sigma}$ (Eulerian, kinetic) -- $\boldsymbol{\sigma}$ — Cauchy stress (Eulerian) -- $\mathbf{P}$ — Nominal (first Piola-Kirchhoff) stress, two-point tensor -- $\dot{\mathbf{E}}$ — Material time derivative of Green-Lagrange strain (Lagrangian, kinematic) -- $\mathbf{D}$ — Rate-of-deformation tensor, $\mathbf{D}=\tfrac12(\mathbf{L}+\mathbf{L}^T)$ (Eulerian, kinematic) -- $\mathbf{L}$ — Spatial velocity gradient, $\mathbf{L}=\dot{\mathbf{F}}\mathbf{F}^{-1}$ (mixed variance) -- $\mathbf{C}$ — Right Cauchy-Green tensor, $\mathbf{C}=\mathbf{F}^T\mathbf{F}$ -- $\mathbf{g}$ — Spatial metric tensor (= $\mathbf{I}$ in Euclidean space) -- $\mathbf{n}_0,\mathbf{n}$ — Outward unit normals on reference / current surfaces -- $d\Gamma_0,d\Gamma$ — Reference / current infinitesimal area elements -- $C^{SE}_{MNPQ}$ — Material tangent stiffness tensor ($\partial \mathbf{S}/\partial \mathbf{E}$) -- $C^{\tau}_{ijkl}$ — Spatial tangent stiffness tensor (push-forward of $C^{SE}$) -- $\mathcal{L}_v$ — Lie derivative along the spatial velocity field $\mathbf{v}$ -- $D/Dt$ — Material time derivative (partial with $\mathbf{X}$ held fixed) - - -## 3. Algorithmic Implementation -**Algorithm: Push-Forward of Second Piola-Kirchhoff Stress to Kirchhoff Stress** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{S} \in \mathbb{R}^{3\times 3},\; \mathbf{F} \in \mathbb{R}^{3\times 3}$ -\State $\mathbf{T} \gets \mathbf{S} \cdot \mathbf{F}^{T} \quad (T_{Ij} = S_{IK}\,F_{jK})$ -\State $\boldsymbol{\tau} \gets \mathbf{F} \cdot \mathbf{T} \quad (\tau_{ij} = F_{iI}\,T_{Ij})$ -\Return $\boldsymbol{\tau}$ -\end{algorithmic} -$$ - -**Algorithm: Pull-Back of Rate-of-Deformation to Rate of Green Strain** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \mathbf{D} \in \mathbb{R}^{3\times 3},\; \mathbf{F} \in \mathbb{R}^{3\times 3}$ -\State $\mathbf{T} \gets \mathbf{D} \cdot \mathbf{F} \quad (T_{iJ} = D_{ik}\,F_{kJ})$ -\State $\dot{\mathbf{E}} \gets \mathbf{F}^{T} \cdot \mathbf{T} \quad (\dot{E}_{IJ} = F_{iI}\,T_{iJ})$ -\Return $\dot{\mathbf{E}}$ -\end{algorithmic} -$$ - -**Algorithm: Index-by-Index Push-Forward of Fourth-Order Tangent (C^SE -> C^tau)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon C^{SE} \in \mathbb{R}^{3\times3\times3\times3},\; \mathbf{F} \in \mathbb{R}^{3\times3}$ -\For{$i,N,P,Q = 1,\ldots,3$} -\State $H^{(1)}_{iNPQ} \gets \sum_{M=1}^{3} F_{iM}\,C^{SE}_{MNPQ}$ -\EndFor -\For{$i,j,P,Q = 1,\ldots,3$} -\State $H^{(2)}_{ijPQ} \gets \sum_{N=1}^{3} F_{jN}\,H^{(1)}_{iNPQ}$ -\EndFor -\For{$i,j,k,Q = 1,\ldots,3$} -\State $H^{(3)}_{ijkQ} \gets \sum_{P=1}^{3} F_{kP}\,H^{(2)}_{ijPQ}$ -\EndFor -\For{$i,j,k,l = 1,\ldots,3$} -\State $C^{\tau}_{ijkl} \gets \sum_{Q=1}^{3} F_{lQ}\,H^{(3)}_{ijkQ}$ -\EndFor -\Return $C^{\tau}$ -\end{algorithmic} -$$ - -**Algorithm: Lie Derivative of Kirchhoff Stress (= convected/Truesdell rate)** - -$$ -\begin{algorithmic} -\State $\text{input} \colon \boldsymbol{\tau}_n,\boldsymbol{\tau}_{n+1} \in \mathbb{R}^{3\times 3},\; \mathbf{L} \in \mathbb{R}^{3\times 3},\; \Delta t > 0$ -\State $\dot{\boldsymbol{\tau}} \gets (\boldsymbol{\tau}_{n+1} - \boldsymbol{\tau}_n)/\Delta t$ -\State $\mathcal{L}_v\boldsymbol{\tau} \gets \dot{\boldsymbol{\tau}} - \mathbf{L}\cdot\boldsymbol{\tau}_{n+1} - \boldsymbol{\tau}_{n+1}\cdot\mathbf{L}^{T}$ -\Return $\mathcal{L}_v\boldsymbol{\tau}$ -\end{algorithmic} -$$ - -## 4. Known Pitfalls -**Confusing kinetic and kinematic transformations:** Applying the kinetic rule $\mathbf{F}(\bullet)\mathbf{F}^T$ to a strain-like quantity (or the kinematic rule $\mathbf{F}^{-T}(\bullet)\mathbf{F}^{-1}$ to a stress) silently destroys work conjugacy. The integrated mechanical power $\int\boldsymbol{\sigma}\colon\mathbf{D}\,dV$ then no longer matches $\int\mathbf{S}\colon\dot{\mathbf{E}}\,dV_0$, energy is created or lost, and convergence in finite-strain Newton iterations degrades or stalls. Rule of thumb: stresses (PK2, $\boldsymbol{\tau}$) push forward with $\mathbf{F}$ on the outside; strains (Green strain, $\mathbf{C}$) pull back with $\mathbf{F}^T$ on the outside. - - -**Loss of work conjugacy under sloppy mixed transformations:** Velocity-gradient-like (mixed-variance) tensors require $\mathbf{F}^{-1}$ on the contravariant leg and $\mathbf{F}$ on the covariant leg, NOT a sandwich of identical operators. A common mistake is treating $\mathbf{L}$ as either purely kinematic or purely kinetic; both choices break the multiplicative split $\mathbf{L}=\mathbf{L}^e+\mathbf{L}^p$ that elastoplastic codes rely on. - - -**Element inversion / vanishing det(F):** Push-forward and pull-back rely on $\mathbf{F}^{-1}$ and $1/J$. Near element inversion ($J\to 0^+$) or full inversion ($J<0$) these become numerically singular and produce NaN tangent moduli that propagate through Newton iterations. Check that $J$ remains admissible before transforming, and never blindly invert $\mathbf{F}$. - - -**Index ordering errors in fourth-order push-forward:** The contraction $C^{\tau}_{ijkl} = F_{iM}F_{jN}F_{kP}F_{lQ}\,C^{SE}_{MNPQ}$ requires that the spatial index appears on the left of each $F$ and the material index on the right. Swapping to $F_{Mi}$ etc. (using $\mathbf{F}^T$ instead of $\mathbf{F}$) silently produces a transposed tangent that still has the right symmetries and passes minor consistency checks but yields a wrong stiffness matrix — typically detectable only via a finite-difference verification of the global tangent. - - -**Lie derivative confused with the material time derivative:** The bare material time derivative $\dot{\boldsymbol{\tau}} = \partial\boldsymbol{\tau}/\partial t |_{\mathbf{X}}$ is NOT objective — under a rigid-body rotation it picks up spurious $\boldsymbol{\Omega}\boldsymbol{\tau}-\boldsymbol{\tau}\boldsymbol{\Omega}$ terms. Constitutive laws must be written in terms of $\mathcal{L}_v\boldsymbol{\tau}$ (or the equivalent Truesdell/Jaumann/Green-Naghdi rates, see `kinematics-objectivity`). Using $\dot{\boldsymbol{\tau}}$ directly in a hyperelastic update produces stress oscillations under simple shear and rotates the principal axes incorrectly under rigid spin. - - -**Voigt notation gotchas for kinetic vs kinematic tensors:** Belytschko's Appendix 1 defines two Voigt rules: the kinematic rule multiplies shear strains by 2 (so $\dot{E}_4 = 2\dot{E}_{23}$, etc.), the kinetic rule does not. When pushing forward a fourth-order tangent stored as a $6\times 6$ Voigt matrix, the strain-like factors and stress-like factors must use opposite Voigt conventions or the resulting tangent is wrong by factors of 2 / 4 in shear blocks. Either convert back to indicial form before transforming, or carry an explicit $\mathbf{T}_{\text{kin}}$ / $\mathbf{T}_{\text{kit}}$ Voigt-mapping matrix and apply $C^{\tau}_{6\times 6} = \mathbf{T}_{\text{kit}}\,C^{SE}_{6\times 6}\,\mathbf{T}_{\text{kit}}^T$ (kinetic Voigt) consistently. - - -**Symmetry on Nyquist / boundary indices not preserved:** $C^{\tau}$ inherits the major and minor symmetries of $C^{SE}$ only if the index-by-index contraction is carried out exactly. Truncation/Voigt tricks can break the minor symmetry $C^{\tau}_{ijkl}=C^{\tau}_{jikl}$, which then violates angular momentum balance at the element level. Always verify $\|C^{\tau}_{ijkl}-C^{\tau}_{jikl}\|/\|C^{\tau}\| < 10^{-12}$ on a unit-cell test. - - -## 5. References -- Belytschko, Liu, Moran & Elkhodary (2014) — Nonlinear Finite Elements for Continua and Structures, 2nd ed. (transformations between stresses; rate-of-deformation pull-back; elasticity tensors and Voigt form; push-forward / pull-back / Lie derivative) -- de Borst, Crisfield, Remmers & Verhoosel (2012) — Nonlinear Finite Element Analysis of Solids and Structures, 2nd ed. (deformation gradient, Jacobian, volume transformation) diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-products-contractions.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-products-contractions.md deleted file mode 100644 index 9e334e0..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-products-contractions.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: tensor-products-contractions -title: Tensor Products & Contractions -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- dyadic-product -- contraction -- fourth-order -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-index-notation - type: requires - weight: 1.0 -- to: tensor-voigt-notation - type: feeds-into - weight: 0.9 -- to: tensor-invariants - type: feeds-into - weight: 0.7 -- to: tensor-derivatives-tensors - type: feeds-into - weight: 0.9 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Tensor Products & Contractions - -## Summary - -Tensor products and contractions form the operational building blocks of continuum mechanics, enabling dyadic product creation, tensor order reduction, and internal power calculations. Special fourth-order tensor products capture non-standard index pairings necessary for constructing consistent algorithmic tangent stiffness matrices. - -## 1. Core Concept - -Tensor products expand lower-order vector or tensor spaces into higher-order tensor structures, while contractions reduce tensor rank by summing over paired indices. Dyadic vector products a \otimes b yield second-order tensors a_i b_j. Double contractions A : B evaluate inner products of second-order tensors A_{ij} B_{ij}, representing work-conjugate energy rates. Contracting a fourth-order tangent tensor \mathbb{C} with a second-order strain tensor E produces a second-order stress tensor \sigma_{ij} = C_{ijkl} E_{kl}. In finite deformation mechanics, specialized fourth-order tensor products (such as (A \bar{\otimes} B)_{ijkl} = A_{ik} B_{jl} and (A \bar{\bar{\otimes}} B)_{ijkl} = A_{il} B_{jk}) express derivatives of non-linear strain metrics and deformation gradients. - -## 2. Mathematical Formulation - -**Single and Double Tensor Contractions** -$$ -A \cdot B = A_{ij} B_{jk} \mathbf{e}_i \otimes \mathbf{e}_k, \quad A : B = A_{ij} B_{ij}, \quad \mathbb{C} : B = C_{ijkl} B_{kl} \mathbf{e}_i \otimes \mathbf{e}_j -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, pp. 777–778; Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, Sec. Notation, p. 47_ - -**Vector Dyadic and Fourth-Order Tensor Products** -$$ -a \otimes b = a_i b_j \mathbf{e}_i \otimes \mathbf{e}_j, \quad A \otimes B = A_{ij} B_{kl} \mathbf{e}_i \otimes \mathbf{e}_j \otimes \mathbf{e}_k \otimes \mathbf{e}_l -$$ -_Source: Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, Sec. Notation, p. 47; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, p. 778_ - -**Specialized Index-Permuted Fourth-Order Tensor Products** -$$ -(A \bar{\otimes} B)_{ijkl} = A_{ik} B_{jl}, \quad (A \bar{\bar{\otimes}} B)_{ijkl} = A_{il} B_{jk} -$$ -_Source: Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, Sec. Notation & App. A, Eqs. A.16 & A.21, pp. 47, 49–50; Generic_anisotropic_thermo-elastoviscoplasticity.pdf, Sec. Notation, p. 123_ - -**Elastic Strain Tangent Derivative via Specialized Tensor Products** -$$ -\frac{\partial E^e}{\partial F^e} = \frac{1}{2} \left( I \bar{\otimes} F^{eT} + F^{eT} \bar{\bar{\otimes}} I \right) -$$ -_Source: Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, Eq. A.21, p. 50_ - -**Notation:** -{'\\otimes': 'Dyadic / tensor product operator.', '\\cdot': 'Single index contraction operator.', ':': 'Double index contraction operator.', '\\bar{\\otimes}, \\bar{\\bar{\\otimes}}': 'Index-permuted fourth-order tensor product operators.', 'A_{ij}, B_{kl}': 'Components of second-order tensors.', 'C_{ijkl}': 'Components of fourth-order tensor.'} - - -## 3. Algorithmic Implementation - -**Fourth-Order Tensor Product and Double Contraction Evaluation Algorithm** -$$ -\begin{algorithmic} -\State $Given second-order tensors A and B with components A_{ij} and B_{ij}$ -\State $Compute double contraction scalar s \gets \sum_{i=1}^3 \sum_{j=1}^3 A_{ij} B_{ij}$ -\State $Evaluate standard 4th-order tensor product (A \otimes B)_{ijkl} \gets A_{ij} B_{kl}$ -\State $Evaluate index-permuted 4th-order product (A \bar{\otimes} B)_{ijkl} \gets A_{ik} B_{jl}$ -\State $Evaluate second permuted product (A \bar{\bar{\otimes}} B)_{ijkl} \gets A_{il} B_{jk}$ -\State $Evaluate double contraction of (A \bar{\otimes} B) with tensor C: \mathbb{H}_{ij} \gets \sum_{k=1}^3 \sum_{l=1}^3 (A \bar{\otimes} B)_{ijkl} C_{kl}$ -\Return $s, A \otimes B, A \bar{\otimes} B, \mathbb{H}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, Sec. Notation, p. 47; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, pp. 777–778_ - - -## 4. Known Pitfalls - -- **Index Order Inversion in Double Contractions**: Failing to maintain proper index ordering when evaluating double contractions A : B. Standard double contraction evaluates A_{ij} B_{ij} (or C_{ijkl} D_{kl}), whereas reversed index contraction A_{ij} B_{ji} is only equivalent when either tensor is symmetric. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Glossary, p. 778; Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, Sec. Notation, p. 47)_ -- **Mismatched Leg Pairing in Fourth-Order Tensor Products**: Substituting standard dyadic product A_{ij} B_{kl} for permuted tensor products A_{ik} B_{jl} or A_{il} B_{jk} during tangent modulus derivations produces incorrect index contractions when evaluating Jacobians and stress updates. _(Source: Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf, App. A, Eqs. A.16 & A.21, pp. 49–50; Generic_anisotropic_thermo-elastoviscoplasticity.pdf, Sec. Notation, p. 123)_ - -## References - -- Abatour et al_2021_A generic formulation of anisotropic thermo-elastoviscoplasticity at finite.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf -- Generic_anisotropic_thermo-elastoviscoplasticity.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-spectral-decomposition.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-spectral-decomposition.md deleted file mode 100644 index 6ad0e9e..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-spectral-decomposition.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -id: tensor-spectral-decomposition -title: Spectral Decomposition of Symmetric Tensors -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- eigenvalues -- eigenprojection -- spectral-decomposition -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-invariants - type: requires - weight: 1.0 - note: Spectral decomposition relies on characteristic equations and tensor invariants -- to: tensor-isotropic-functions - type: feeds-into - weight: 1.0 - note: Spectral representations enable scalar evaluation of isotropic tensor functions -- to: tensor-derivatives-tensors - type: feeds-into - weight: 1.0 - note: Derivative expressions for isotropic tensor functions utilize eigenprojections -- to: kinematics-polar-decomposition - type: feeds-into - weight: 0.9 - note: Polar stretch tensors U and V are evaluated via square roots of C and b spectra -- to: pf-spectral-split - type: feeds-into - weight: 0.8 - note: Constitutive strain/stress splits use spectral projection operators -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Spectral Decomposition of Symmetric Tensors - -## Summary - -Spectral decomposition represents a symmetric second-order tensor in terms of its real eigenvalues (principal values) and orthonormal eigenvectors (principal directions) or eigenprojections. This formulation reduces tensor operations, such as fractional powers, logarithms, and isotropic stress-strain return mappings, to scalar functions evaluated along principal axes. - -## 1. Core Concept - -Any symmetric second-order tensor in continuum mechanics (such as the right Cauchy-Green tensor C, Cauchy stress tensor sigma, or strain tensor) possesses three real eigenvalues and a set of mutually orthogonal principal directions. In spectral form, the tensor is expressed either as a sum of outer products of its orthonormal eigenvectors or as a linear combination of its rank-one eigenprojection matrices. This transformation simplifies non-linear isotropic tensor functions—including logarithmic strains, hyperelastic stored energy potentials, and yield criteria—by decoupling the tensor into independent scalar operations in principal space. - -## 2. Mathematical Formulation - -**Characteristic Equation and Principal Invariants** -$$ -\det(C - \lambda I) = -\lambda^3 + I_1 \lambda^2 - I_2 \lambda + I_3 = 0 -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.2, Eqs. 1.83–1.86, p. 20; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, App. A, p. 28_ - -**Spectral Decomposition and Eigenprojections** -$$ -C = \sum_{i=1}^3 \lambda_i e_i \otimes e_i = \sum_{i=1}^3 \lambda_i E_i, \quad E_i = e_i \otimes e_i, \quad \sum_{i=1}^3 E_i = I -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.2, Eqs. 1.69–1.71, p. 16_ - -**Isotropic Tensor Function Evaluation** -$$ -f(C) = \sum_{i=1}^3 f(\lambda_i) E_i, \quad \ln U = \frac{1}{2} \ln C = \sum_{i=1}^3 (\ln \lambda_i) E_i -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 11.8, Eq. 11.108, p. 388; Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf, Def. 2.16, p. 8; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 3.7.1, p. 131_ - -**Closed-Form Principal Stress via Lode Angle** -$$ -\begin{pmatrix} \sigma_1 \\ \sigma_2 \\ \sigma_3 \end{pmatrix} = 2 \sqrt{\frac{J_2}{3}} \begin{pmatrix} \sin(\theta - 2\pi/3) \\ \sin(\theta) \\ \sin(\theta + 2\pi/3) \end{pmatrix} + p \begin{pmatrix} 1 \\ 1 \\ 1 \end{pmatrix}, \quad \sin(3\theta) = \frac{-J_3}{2 (J_2/3)^{3/2}} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 7.3.5, Eqs. 7.164–7.165, p. 261_ - -**Notation:** -{'C': 'Symmetric second-order tensor (e.g., right Cauchy-Green deformation tensor).', '\\lambda_i': 'Principal values (eigenvalues) of tensor C.', 'e_i': 'Orthonormal unit eigenvectors (principal directions).', 'E_i': 'Eigenprojection tensor e_i \\otimes e_i.', 'I_1, I_2, I_3': 'Principal invariants of a second-order tensor.', 'J_2, J_3': 'Second and third invariants of the deviatoric stress tensor.', '\\theta': 'Lode angle defined in deviatoric stress space.', 'p': 'Hydrostatic mean stress p = (1/3) tr(\\sigma).'} - - -## 3. Algorithmic Implementation - -**Spectral Decomposition and Isotropic Function Evaluation Algorithm** -$$ -\begin{algorithmic} -\State $Given symmetric 3x3 tensor C and scalar function f(\cdot)$ -\State $Compute principal invariants I_1 = \mathrm{tr}(C), I_2 = \frac{1}{2}[(\mathrm{tr} C)^2 - \mathrm{tr}(C^2)], I_3 = \det(C)$ -\State $Solve characteristic polynomial -\lambda^3 + I_1 \lambda^2 - I_2 \lambda + I_3 = 0 \text{ for eigenvalues } \lambda_1, \lambda_2, \lambda_3$ -\If{$\lambda_1, \lambda_2, \lambda_3 \text{ are distinct } (\lambda_1 \neq \lambda_2 \neq \lambda_3)$} -\For{$i \gets 1 \text{ to } 3$} -\State $Compute eigenprojection E_i \gets \frac{\lambda_i}{2\lambda_i^3 - I_1 \lambda_i^2 + I_3} \left( C^2 - (I_1 - \lambda_i)C + I_3 I \right)$ -\EndFor -\ElsIf{$\text{Two eigenvalues are equal } (\lambda_1 \neq \lambda_2 = \lambda_3)$} -\State $Evaluate degenerate eigenprojections via E_1 \gets \frac{C - \lambda_2 I}{\lambda_1 - \lambda_2} \text{ and } E_2 \gets I - E_1$ -\Else -\State $Set E_1 \gets I \text{ and } E_2 \gets 0, E_3 \gets 0$ -\EndIf -\State $Evaluate tensor function f(C) \gets \sum_{i=1}^3 f(\lambda_i) E_i$ -\Return $f(C)$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 1.1, p. 16, Sec. 11.8, p. 388, & Box 11.3, p. 387_ - - -## 4. Known Pitfalls - -- **Ill-Conditioned Eigenprojection Formulas Near Coinciding Eigenvalues**: Using distinct-eigenvalue closed-form expressions for eigenprojections E_i when two or three eigenvalues are nearly equal causes division by near-zero denominators (\(\lambda_i - \lambda_j \to 0\)), leading to extreme loss of numerical precision. Mitigation: Use explicit degenerate branching conditions (such as \(E_1 = (C - \lambda_2 I)/(\lambda_1 - \lambda_2)\) when \(\lambda_2 = \lambda_3\), or \(E_1 = I\) when \(\lambda_1 = \lambda_2 = \lambda_3\)) when eigenvalues coincide. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Box 11.3, p. 387)_ -- **Round-Off Error in Lode Angle Arccos/Arcsin Bounds**: Numerical floating-point round-off can cause the argument of \(\sin(3\theta) = -J_3 / [2(J_2/3)^{3/2}]\) to slightly exceed 1.0 or fall below -1.0 in magnitude, causing domain errors in inverse trigonometric functions. Mitigation: Clamp the argument to [-1, 1] prior to evaluating the arcsin or Lode angle. _(Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 7.3.5, Eq. 7.165, p. 261)_ - -## References - -- Aubram_2017_Notes on rate equations in nonlinear continuum mechanics.pdf -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/tensor-voigt-notation.md b/packages/akms/src/akms/_bundled/global_nodes/tensor-voigt-notation.md deleted file mode 100644 index 581e127..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/tensor-voigt-notation.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -id: tensor-voigt-notation -title: Voigt Notation for Symmetric Tensors -domain: computational-mechanics -subdomain: tensor-algebra -tags: -- tensors -- continuum-mechanics -- voigt -- tensor-notation -- matrix-free -status: established -confidence: 0.9 -source: hybrid -edges: -- to: tensor-products-contractions - type: requires - weight: 0.9 -- to: tensor-mandel-notation - type: feeds-into - weight: 1.0 -- to: fem-tl-b-matrix - type: feeds-into - weight: 1.0 -- to: plasticity-consistent-tangent-general - type: feeds-into - weight: 0.9 -context_size: small -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Voigt Notation for Symmetric Tensors - -## Summary - -Voigt notation compresses symmetric second-order tensors into column vectors and fourth-order tangent moduli into 6x6 matrices. By doubling kinematic shear strain components, Voigt array operations preserve energy inner products and work conjugacy in finite element implementations. - -## 1. Core Concept - -In computational solid mechanics, storing symmetric 3x3 second-order tensors as 6x1 column vectors and 4th-order tangent operators as 6x6 matrices reduces storage memory and enables matrix-vector operations. Voigt notation enforces a distinct rule for kinetic tensors (such as Cauchy stress \boldsymbol{\sigma} or Second Piola-Kirchhoff stress \mathbf{S}) versus kinematic tensors (such as Green-Lagrange strain \mathbf{E} or rate of deformation \mathbf{D}). Kinetic vectors store unscaled tensor components \{\sigma\} = [\sigma_{11}, \sigma_{22}, \sigma_{33}, \sigma_{23}, \sigma_{13}, \sigma_{12}]^T. Kinematic vectors double the off-diagonal shear components to store engineering shear strains \gamma_{ij} = 2\varepsilon_{ij}, yielding \{\varepsilon\} = [\varepsilon_{11}, \varepsilon_{22}, \varepsilon_{33}, 2\varepsilon_{23}, 2\varepsilon_{13}, 2\varepsilon_{12}]^T. This factor-of-two scaling ensures that vector dot products match tensor double contractions \boldsymbol{\sigma} : \boldsymbol{\varepsilon} = \{\sigma\}^T \{\varepsilon\}, preserving virtual work expressions. - -## 2. Mathematical Formulation - -**Kinetic and Kinematic Voigt Vector Mappings** -$$ -\{\sigma\} = \begin{bmatrix} \sigma_{11} \\ \sigma_{22} \\ \sigma_{33} \\ \sigma_{23} \\ \sigma_{13} \\ \sigma_{12} \end{bmatrix}, \quad \{\varepsilon\} = \begin{bmatrix} \varepsilon_{11} \\ \varepsilon_{22} \\ \varepsilon_{33} \\ 2\varepsilon_{23} \\ 2\varepsilon_{13} \\ 2\varepsilon_{12} \end{bmatrix} = \begin{bmatrix} \varepsilon_{11} \\ \varepsilon_{22} \\ \varepsilon_{33} \\ \gamma_{23} \\ \gamma_{13} \\ \gamma_{12} \end{bmatrix} -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Appendix 1, Eqs. A.1.1–A.1.4, pp. 751–752; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.3, p. 22_ - -**Work Conjugacy Preservation in Voigt Form** -$$ -\delta W^{\mathrm{int}} = \int_V \boldsymbol{\sigma} : \delta \boldsymbol{\varepsilon} \, \mathrm{d}V = \int_V \{\sigma\}^T \{\delta \varepsilon\} \, \mathrm{d}V -$$ -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Appendix 1, Eq. A.1.5, p. 752; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.3, p. 22_ - -**Isotropic Elasticity Modulus Matrix in Voigt Notation** -$$ -\{\sigma\} = [D^{\mathrm{e}}] \{\varepsilon\}, \quad [D^{\mathrm{e}}] = \frac{E}{(1+\nu)(1-2\nu)} \begin{bmatrix} 1-\nu & \nu & \nu & 0 & 0 & 0 \\ \nu & 1-\nu & \nu & 0 & 0 & 0 \\ \nu & \nu & 1-\nu & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{1-2\nu}{2} & 0 & 0 \\ 0 & 0 & 0 & 0 & \frac{1-2\nu}{2} & 0 \\ 0 & 0 & 0 & 0 & 0 & \frac{1-2\nu}{2} \end{bmatrix} -$$ -_Source: Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.4, Eq. 1.115, p. 25; Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Sec. 5.4, Eq. 5.4.9, p. 243_ - -**Notation:** -{'\\{\\sigma\\}': '6x1 kinetic stress vector array.', '\\{\\varepsilon\\}': '6x1 kinematic strain vector array.', '\\gamma_{ij}': 'Engineering shear strain \\gamma_{ij} = 2\\varepsilon_{ij} (i \\neq j).', '[D^{\\mathrm{e}}]': '6x6 elastic material stiffness matrix.', '\\delta W^{\\mathrm{int}}': 'Internal virtual work rate scalar.'} - - -## 3. Algorithmic Implementation - -**Voigt Conversion and Internal Force Vector Assembly Algorithm** -$$ -\begin{algorithmic} -\State $Given 3x3 symmetric Second Piola-Kirchhoff stress S_{ij} and 3x3 strain tensor E_{ij}$ -\State $Construct kinetic stress vector \{S\} \gets [S_{11}, S_{22}, S_{33}, S_{23}, S_{13}, S_{12}]^T$ -\State $Construct kinematic strain vector \{E\} \gets [E_{11}, E_{22}, E_{33}, 2E_{23}, 2E_{13}, 2E_{12}]^T$ -\State $Verify internal energy density rate equivalence: \dot{w} \gets \{S\}^T \{\dot{E}\} = S_{ij} \dot{E}_{ij}$ -\State $Compute internal force contribution: \mathbf{f}^{\mathrm{int}}_I \gets \int_{\Omega_0} \mathbf{B}_{0I}^T \{S\} \, \mathrm{d}\Omega_0$ -\Return $\{S\}, \{E\}, \mathbf{f}^{\mathrm{int}}_I$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 4.6 & Appendix 1, pp. 211, 751–752; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.3 & 3.4.1, pp. 22, 94_ - - -## 4. Known Pitfalls - -- **Omitting Factor of Two in Kinematic Strain Vector Components**: Converting symmetric second-order strain tensors E_{ij} into Voigt vectors using tensor shear components \varepsilon_{ij} instead of engineering shear strains \gamma_{ij} = 2\varepsilon_{ij}. Omitting the factor of two causes an incorrect evaluation of internal energy rates \{S\}^T \{E\} \neq \mathbf{S} : \mathbf{E} and corrupts shear terms in material stiffness matrices. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Appendix 1, p. 752; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf, Sec. 1.3, p. 22)_ -- **Applying Matrix Operations to Two-Point Tensors in Voigt Form**: Attempting to perform coordinate transformations or push-forward operations on Voigt vectors using 6x6 transformations designed for symmetric tensors on two-point non-symmetric operators (such as deformation gradient F). Push-forward operations must be evaluated in tensor form \boldsymbol{\tau} = \mathbf{F} \mathbf{S} \mathbf{F}^T before mapping to Voigt vectors. _(Source: Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf, Box 4.6 & Appendix 1, pp. 211, 751–752)_ - -## References - -- Belytschko_Nonlinear Finite Elements for Continua and Structures.pdf -- Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/thermal-adiabatic-shear.md b/packages/akms/src/akms/_bundled/global_nodes/thermal-adiabatic-shear.md deleted file mode 100644 index 66ab2cf..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/thermal-adiabatic-shear.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: thermal-adiabatic-shear -title: Adiabatic Shear Band Formation -domain: computational-mechanics -subdomain: thermal -tags: -- thermal -- adiabatic-shear -- localization -- plasticity -- regularisation -status: established -confidence: 0.9 -source: hybrid -edges: -- to: thermal-softening - type: requires - weight: 1.0 -- to: thermal-coupled-mechanics - type: requires - weight: 1.0 -- to: plasticity-perzyna - type: feeds-into - weight: 0.8 -- to: damage-spall - type: refines - weight: 0.6 -context_size: large -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Adiabatic Shear Band Formation - -## Summary - -Adiabatic shear band formation is a thermal-mechanical instability in high-strain-rate metal deformation, driven by plastic work conversion to heat and subsequent thermal softening. - -## 1. Core Concept - -Adiabatic shear localization occurs during high-rate plastic deformation when heat generated by plastic dissipation cannot conduct away fast enough, causing local thermal softening that overcomes strain hardening. This destabilizes uniform deformation, concentrating plastic strain into narrow bands. The onset of adiabatic shear instability occurs when the material rate of stress response reaches a peak, d\tau/d\gamma = 0 under adiabatic conditions. Numerical modeling uses power-law viscoplastic flow laws with thermal softening exponents and Taylor-Quinney plastic work conversion factors \beta_0, coupled with damage or phase-field formulations to capture post-instability stress drop. - -## 2. Mathematical Formulation - -**Viscoplastic Flow Stress with Thermal Softening** -$$ -\tau = g_0 \left(1 + \frac{\gamma}{\gamma_0}\right)^n \left[\frac{\theta}{\theta_0}\right]^\nu \left[\frac{\dot{\gamma}}{\dot{\gamma}_0}\right]^m -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 18_ - -**Adiabatic Plastic Work Energy Balance** -$$ -c_V \dot{\theta} = \beta_0 \tau \dot{\gamma} + \nabla \cdot (\kappa \nabla \theta) -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 7; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 275_ - -**Adiabatic Shear Instability Criterion** -$$ -\frac{d\tau}{d\gamma} = 0 \implies \frac{\partial \tau}{\partial \gamma} + \frac{\beta_0 \tau}{c_V} \frac{\partial \tau}{\partial \theta} = 0 -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 28_ - -**Threshold Plastic Energy Density for Localization** -$$ -W^{\phi}_0 = \int_0^{\gamma_c} \tau(\gamma) \, d\gamma -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 1, 28_ - -**Notation:** -\tau: Cauchy shear stress; \gamma: plastic shear strain; \dot{\gamma}: shear strain rate; \theta: absolute temperature; c_V: volumetric heat capacity; \beta_0: Taylor-Quinney coefficient; g_0: initial yield strength; n: strain hardening exponent; \nu: thermal softening exponent; m: strain rate sensitivity parameter; \kappa: thermal conductivity; W^{\phi}_0: threshold energy density for localization; \gamma_c: critical localization strain. - - -## 3. Algorithmic Implementation - -**Adiabatic Shear Localization and Temperature Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given initial temperature } \theta_n, \text{ shear strain } \gamma_n, \text{ strain increment } \Delta \gamma, \text{ and heat capacity } c_V$ -\State $\tau_n = g_0 \left(1 + \frac{\gamma_n}{\gamma_0}\right)^n \left[\frac{\theta_n}{\theta_0}\right]^\nu \left[\frac{\Delta \gamma}{\Delta t \dot{\gamma}_0}\right]^m$ -\State $\Delta \theta = \frac{\beta_0 \tau_n \Delta \gamma}{c_V}$ -\State $\theta_{n+1} = \theta_n + \Delta \theta, \quad \gamma_{n+1} = \gamma_n + \Delta \gamma$ -\State $\tau_{n+1} = g_0 \left(1 + \frac{\gamma_{n+1}}{\gamma_0}\right)^n \left[\frac{\theta_{n+1}}{\theta_0}\right]^\nu \left[\frac{\Delta \gamma}{\Delta t \dot{\gamma}_0}\right]^m$ -\State $\text{Evaluate slope residual } R_{\text{inst}} = \frac{\tau_{n+1} - \tau_n}{\Delta \gamma}$ -\If{$R_{\text{inst}} \le 0$} -\State $\text{Instability criterion } d\tau/d\gamma \le 0 \text{ met; localization initiates}$ -\Else -\EndIf -\Return $\text{Return updated shear stress } \tau_{n+1}, \text{ temperature } \theta_{n+1}, \text{ and strain } \gamma_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 18, 28; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 275-276_ - - -## 4. Known Pitfalls - -- **Spurious Mesh Sensitivity in Local Unregularized Softening Models**: Omitting strain-rate sensitivity m or thermal heat conduction \kappa in finite element simulations of thermal softening causes shear localization to collapse onto a single element width, resulting in unphysical mesh dependency. _(Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 2; Borst_Crisfield_2012_Nonlinear finite element analysis of solids and structures.pdf p. 179-181)_ -- **Extrapolating Flow Stress Past Melting Temperature**: Evaluating thermal softening functions [\theta / \theta_0]^\nu as temperature \theta approaches or exceeds the material melting temperature \theta_T leads to singular or invalid stress states unless phase transition latent heat absorption is incorporated. _(Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 1, 30)_ - -## References - -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/thermal-coupled-mechanics.md b/packages/akms/src/akms/_bundled/global_nodes/thermal-coupled-mechanics.md deleted file mode 100644 index 87c1922..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/thermal-coupled-mechanics.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: thermal-coupled-mechanics -title: Thermo-Mechanical Coupling -domain: computational-mechanics -subdomain: thermal -tags: -- thermal -- coupling -- heat-equation -- staggered -- monolithic -status: established -confidence: 0.9 -source: hybrid -edges: -- to: thermal-softening - type: requires - weight: 1.0 -- to: constit-thermodynamic-framework - type: requires - weight: 1.0 -- to: fem-newton-raphson - type: feeds-into - weight: 0.9 -- to: thermal-adiabatic-shear - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Thermo-Mechanical Coupling - -## Summary - -Thermo-mechanical coupling formulates the dynamic interaction between mechanical deformation, plastic strain energy dissipation, thermal expansion, and heat conduction in inelastic solids. - -## 1. Core Concept - -Thermo-mechanical coupling governs the bidirectional interaction between mechanical strain and thermal energy fields in solid continuum mechanics. Plastic deformation converts mechanical work into heat through the Taylor-Quinney dissipation factor \chi (or \beta_0), generating a thermal heat source \chi W_p that elevates temperature T according to heat conduction principles \rho c_V \dot{T} = \chi W_p + \kappa \nabla^2 T. Thermally induced temperature changes feed back into the mechanical field via volumetric thermal expansion strain \dot{\bm{\varepsilon}}_t = \alpha \dot{T} \mathbf{I} and temperature-dependent flow stress softening. Computational solution frameworks utilize staggered operator-split schemes or coupled internal energy balance equations E_{n+1} - \tilde{E}(\bm{\varepsilon}^e_{n+1}, D_{n+1}, T_{n+1}) = 0 to integrate thermo-mechanical return mapping over discrete time steps. - -## 2. Mathematical Formulation - -**Coupled Heat Conduction Energy Equation** -$$ -\rho \hat{c} \dot{T} = \chi W_p + \kappa \nabla^2 T, \quad W_p = \bm{\sigma} : \dot{\bm{\varepsilon}}^p -$$ -_Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 280; Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 7_ - -**Isotropic Thermal Expansion Strain Rate** -$$ -\dot{\bm{\varepsilon}}_t = \alpha \dot{T} \mathbf{I} -$$ -_Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 280_ - -**Internal Energy Balance Equation in IEOS Framework** -$$ -E_{n+1} - \tilde{E}(\bm{\varepsilon}^e_{n+1}, D_{n+1}, T_{n+1}) = 0 -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 287, 288_ - -**Thermo-Mechanical Stress Return Mapping** -$$ -\bm{\sigma}_{n+1} = J_{n+1}^{-1} \frac{\partial \tilde{\Psi}(\bm{\varepsilon}^e_{n+1}, D_{n+1}, T_{n+1})}{\partial \bm{\varepsilon}^e_{n+1}} -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 285, 288_ - -**Notation:** -\rho: material density; \hat{c}, c_V: specific heat capacity; T: absolute temperature; \chi, \beta_0: Taylor-Quinney conversion parameter; W_p: plastic dissipation work rate; \kappa: thermal conductivity; \alpha: thermal expansion coefficient; \bm{\varepsilon}_t: thermal strain tensor; \mathbf{I}: identity tensor; E: specific internal energy; \tilde{E}: Helmholtz/internal energy potential; D: damage variable; \bm{\sigma}: Cauchy stress tensor; \bm{\varepsilon}^e: elastic logarithmic strain tensor. - - -## 3. Algorithmic Implementation - -**Staggered Thermo-Mechanical Solution Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: displacement } \mathbf{u}_n, \text{ temperature } T_n, \text{ plastic strain } \bm{\varepsilon}^p_n, \text{ damage } D_n, \text{ and strain increment } \Delta \bm{\varepsilon}$ -\State $\Delta \bm{\varepsilon}_t = \alpha (T_n - T_{n-1}) \mathbf{I}, \quad \Delta \bm{\varepsilon}_e = \Delta \bm{\varepsilon} - \Delta \bm{\varepsilon}_t$ -\State $\bm{\sigma}^{\mathrm{tr}} = \bm{\sigma}_n + \mathbf{D}^e : \Delta \bm{\varepsilon}_e, \quad F^{\mathrm{tr}} = F(\bm{\sigma}^{\mathrm{tr}}, \bar{\varepsilon}_n, T_n)$ -\If{$F^{\mathrm{tr}} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}}, \quad \Delta W_p = 0$ -\Else -\State $\Delta W_p = \bm{\sigma}_{n+1} : \Delta \bm{\varepsilon}^p_{n+1}$ -\EndIf -\State $\text{Solve thermal heat equation residual } R_T = \rho \hat{c} \frac{T_{n+1} - T_n}{\Delta t} - \frac{\chi \Delta W_p}{\Delta t} - \kappa \nabla^2 T_{n+1} = 0 \text{ for } T_{n+1}$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ temperature } T_{n+1}, \text{ and plastic work } W_p$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf Algorithm 1, p. 280-281; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 228_ - - -## 4. Known Pitfalls - -- **Unphysical Thermal Softening Extrapolation Above Melting Point**: Evaluating temperature-dependent yield stress functions at temperatures T approaching or exceeding the melting temperature T_m without bounding thermal softening causes flow stress to become negative or singular. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277; Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 30)_ -- **Energy Residual Accumulation in Staggered Thermo-Mechanical Solvers**: Updating temperature T independently from stress return mapping without enforcing unified internal energy balance E_{n+1} - \tilde{E} = 0 accumulates numerical energy residuals during dynamic impact simulations. _(Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 280, 284, 287)_ - -## References - -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/_bundled/global_nodes/thermal-softening.md b/packages/akms/src/akms/_bundled/global_nodes/thermal-softening.md deleted file mode 100644 index e2d5640..0000000 --- a/packages/akms/src/akms/_bundled/global_nodes/thermal-softening.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: thermal-softening -title: Thermal Softening in Constitutive Models -domain: computational-mechanics -subdomain: thermal -tags: -- thermal -- softening -- taylor-quinney -- dynamic-plasticity -- johnson-cook -status: established -confidence: 0.9 -source: hybrid -edges: -- to: constit-thermodynamic-framework - type: requires - weight: 0.9 -- to: plasticity-johnson-cook - type: feeds-into - weight: 1.0 -- to: thermal-coupled-mechanics - type: feeds-into - weight: 1.0 -- to: thermal-adiabatic-shear - type: feeds-into - weight: 1.0 -context_size: medium -reading_priority: full -content_ref: null -akms_schema: v2 ---- - -# Thermal Softening in Constitutive Models - -## Summary - -Thermal softening reduces material flow stress as temperature increases due to plastic work dissipation or thermal environmental loading. - -## 1. Core Concept - -Thermal softening represents the degradation of material flow stress caused by increasing temperature in dynamic plasticity and thermoplasticity. Under high-strain-rate adiabatic deformation, mechanical plastic work is converted into heat via the Taylor-Quinney coefficient \beta_0, raising temperature according to c_V \dot{T} = \beta_0 \bm{\sigma} : \dot{\bm{\varepsilon}}^p. This temperature rise competes against strain and strain-rate hardening. Standard constitutive models capture thermal softening using power-law functions [\theta / \theta_0]^\nu (\nu < 0) or homologous temperature functions [1 - (\theta(T))^m], where \theta(T) = (T - T_r)/(T_m - T_r). - -## 2. Mathematical Formulation - -**Power-Law Thermal Softening Flow Stress** -$$ -Y(\gamma, \theta, \dot{\gamma}) = g_0 \left( 1 + \frac{\gamma}{\gamma_0} \right)^n \left[ \frac{\theta}{\theta_0} \right]^\nu \left[ \frac{\dot{\gamma}}{\dot{\gamma}_0} \right]^m -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 18_ - -**Homologous Temperature Thermal Softening Function** -$$ -g_t(T) = 1 - \left( \theta(T) \right)^m, \quad \theta(T) = \frac{T - T_r}{T_m - T_r} -$$ -_Source: Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277; Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf p. 198_ - -**Adiabatic Plastic Heat Generation Rate Equation** -$$ -c_V \dot{T} = \beta_0 \bm{\sigma} : \dot{\bm{\varepsilon}}^p -$$ -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 7; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 280_ - -**Notation:** -\bm{\sigma}: Cauchy stress tensor; \dot{\bm{\varepsilon}}^p: plastic strain rate tensor; Y: flow stress; g_0: initial yield stress; \gamma: plastic shear strain; \dot{\gamma}: shear strain rate; \theta, T: absolute temperature; T_r: reference room temperature; T_m: melting temperature; \theta(T): homologous temperature; \nu: power-law thermal softening exponent; m: thermal softening exponent; c_V: volumetric heat capacity; \beta_0: Taylor-Quinney dissipation coefficient. - - -## 3. Algorithmic Implementation - -**Adiabatic Thermal Softening and Temperature Integration Algorithm** -$$ -\begin{algorithmic} -\State $\text{Given state at } t_n\text{: stress } \bm{\sigma}_n, \text{ plastic strain } \bar{\varepsilon}_n, \text{ temperature } T_n, \text{ strain increment } \Delta \bm{\varepsilon}, \text{ and heat capacity } c_V$ -\State $\theta_n = \frac{T_n - T_r}{T_m - T_r}, \quad Y_n = Y_0(\bar{\varepsilon}_n, \dot{\bar{\varepsilon}}_n) \left[ 1 - \theta_n^m \right]$ -\State $\bm{\sigma}^{\mathrm{tr}} = \bm{\sigma}_n + \mathbf{D}^e : \Delta \bm{\varepsilon}, \quad f^{\mathrm{tr}} = \bar{\sigma}^{\mathrm{tr}} - Y_n$ -\If{$f^{\mathrm{tr}} \le 0$} -\State $\bm{\sigma}_{n+1} = \bm{\sigma}^{\mathrm{tr}}, \quad T_{n+1} = T_n, \quad \bar{\varepsilon}_{n+1} = \bar{\varepsilon}_n$ -\Return $\text{Step is elastic; return trial state}$ -\Else -\EndIf -\State $\Delta W_p = \bm{\sigma}_{n+1} : \Delta \bm{\varepsilon}^p_{n+1}$ -\State $\Delta T = \frac{\beta_0 \Delta W_p}{c_V}, \quad T_{n+1} = T_n + \Delta T$ -\Return $\text{Return updated Cauchy stress } \bm{\sigma}_{n+1}, \text{ plastic strain } \bar{\varepsilon}_{n+1}, \text{ and temperature } T_{n+1}$ -\end{algorithmic} -$$ -Taichi Mapping: [INSUFFICIENT SOURCE] -_Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 7, 18; Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 280-281; Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277-278_ - - -## 4. Known Pitfalls - -- **Extrapolation Beyond Material Melting Temperature**: Evaluating thermal softening functions at temperatures T \ge T_m causes homologous temperature \theta \ge 1, driving flow stress to zero or negative unphysical values unless phase transformation latent heat absorption is enforced. _(Source: Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 30; Sanchez - 2021 - Inelastic equation of state for solids.pdf p. 277)_ -- **Neglecting Thermal Heat Conduction in Quasi-Static Softening Regimes**: Assuming fully adiabatic conditions (\kappa = 0) during low-strain-rate deformation overpredicts temperature rise and thermal softening, underestimating material load capacity. _(Source: Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf p. 280; Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf p. 7)_ - -## References - -- Clayton - 2025 - Analysis of adiabatic shear coupled to ductile fracture and melting in viscoplastic metals.pdf -- Han et al. - 2024 - Study of the dynamic impact spalling of ductile materials based on Gurson-type phase-field model.pdf -- Pascon and Waisman - 2022 - A gradient-enhanced formulation for thermoviscoplastic metals accounting for ductile damage.pdf -- Sanchez - 2021 - Inelastic equation of state for solids.pdf diff --git a/packages/akms/src/akms/cli/commands.py b/packages/akms/src/akms/cli/commands.py index aa42839..337720a 100644 --- a/packages/akms/src/akms/cli/commands.py +++ b/packages/akms/src/akms/cli/commands.py @@ -857,6 +857,11 @@ def build_parser() -> argparse.ArgumentParser: register_provider_commands(subparsers) + # # Global vault status / install (separate module). + from akms.cli.vault_commands import register_vault_commands + + register_vault_commands(subparsers) + return parser diff --git a/packages/akms/src/akms/cli/vault_commands.py b/packages/akms/src/akms/cli/vault_commands.py new file mode 100644 index 0000000..b4fbff2 --- /dev/null +++ b/packages/akms/src/akms/cli/vault_commands.py @@ -0,0 +1,311 @@ +"""CLI commands for inspecting and installing a global node vault. + +The node corpus is not shipped inside the ``akms`` wheel. It never was +reachable from one: ``resolve_global_vault`` picks an explicit argument, then +``AKMS_GLOBAL_VAULT``, then ``global_vault`` from the propagation config, then +``~/.claude/akms/nodes`` — the package directory is on none of those paths. A +corpus bundled into the package could only ever be dead weight, so vaults are +distributed on their own and installed here, deliberately, by the user. + +That "by the user" is the whole design. Nothing in AKMS writes to the global +vault on its own; ``vault install`` is a foreground command that says what it +is about to do and refuses to overwrite an existing vault without ``--force``. + +Registered via :func:`register_vault_commands`. +""" + +from __future__ import annotations + +import argparse +import json +import shutil +import sys +import tarfile +import tempfile +from pathlib import Path +from typing import Any + +# Set this once the canonical vault publishes its first tagged release; until +# then a source must be given explicitly rather than guessed at. +DEFAULT_VAULT_SOURCE: str | None = None + + +class VaultInstallError(RuntimeError): + """Raised when a vault cannot be fetched, validated, or installed.""" + + +def _count_nodes(directory: Path) -> tuple[int, int]: + """Return (markdown files, files that declare ``akms_schema``). + + Deliberately cheap and tolerant: this is a sanity check on a downloaded + archive, not schema validation. The graph compiler does the real parsing + and reports precisely what it rejects. + """ + md = 0 + schema = 0 + for path in directory.rglob("*.md"): + if path.name.startswith("."): + continue + if "content" in path.relative_to(directory).parts[:-1]: + continue + md += 1 + try: + head = path.read_text(encoding="utf-8", errors="replace")[:2048] + except OSError: + continue + if "akms_schema" in head: + schema += 1 + return md, schema + + +def _safe_extract(archive: Path, dest: Path) -> None: + """Extract a tar archive, refusing members that escape ``dest``. + + Uses the stdlib ``data`` filter where available (3.12, and 3.11.4+), which + rejects absolute paths, parent traversal, links pointing outside the tree, + device nodes and setuid bits. The explicit check below is not redundant: + it keeps the guarantee on interpreters whose tarfile predates the filter, + and it states the invariant at the call site rather than trusting a + default that has changed across versions. + """ + dest_resolved = dest.resolve() + with tarfile.open(archive, "r:*") as tar: + for member in tar.getmembers(): + target = (dest_resolved / member.name).resolve() + if not target.is_relative_to(dest_resolved): + raise VaultInstallError( + f"archive member {member.name!r} escapes the destination " + "directory; refusing to extract" + ) + if member.issym() or member.islnk(): + link = (target.parent / member.linkname).resolve() + if not link.is_relative_to(dest_resolved): + raise VaultInstallError( + f"archive member {member.name!r} links outside the " + "destination directory; refusing to extract" + ) + try: + tar.extractall(dest_resolved, filter="data") + except TypeError: # tarfile without the filter argument + tar.extractall(dest_resolved) # noqa: S202 - members checked above + + +def _fetch(source: str, workdir: Path) -> Path: + """Resolve ``source`` to a directory of vault content inside ``workdir``.""" + staged = workdir / "staged" + + if source.startswith(("http://", "https://")): + if source.startswith("http://"): + raise VaultInstallError( + "refusing to fetch a vault over plain http; use https" + ) + import urllib.request + + archive = workdir / "vault.tar.gz" + try: + with urllib.request.urlopen(source) as response: # noqa: S310 - https enforced + archive.write_bytes(response.read()) + except OSError as exc: + raise VaultInstallError(f"could not download {source}: {exc}") from exc + staged.mkdir() + _safe_extract(archive, staged) + return _descend_single_root(staged) + + local = Path(source).expanduser() + if local.is_dir(): + return local + if local.is_file() and "".join(local.suffixes[-2:]) in {".tar.gz", ".tgz"}: + staged.mkdir() + _safe_extract(local, staged) + return _descend_single_root(staged) + raise VaultInstallError( + f"{source!r} is not a directory, a .tar.gz, or an https URL" + ) + + +def _descend_single_root(staged: Path) -> Path: + """A GitHub tarball wraps everything in one ``repo-tag/`` directory.""" + entries = [p for p in staged.iterdir() if not p.name.startswith(".")] + if len(entries) == 1 and entries[0].is_dir(): + return entries[0] + return staged + + +def cmd_vault_status(args: argparse.Namespace) -> int: + """Report where the vault resolves and what is in it.""" + from akms.graph.build_graph import resolve_global_vault + + vault = resolve_global_vault(explicit=args.vault) + exists = vault.is_dir() + md, schema = _count_nodes(vault) if exists else (0, 0) + + info: dict[str, Any] = { + "vault": str(vault), + "exists": exists, + "markdown_files": md, + "nodes_declaring_akms_schema": schema, + } + if args.json: + print(json.dumps(info, indent=2, sort_keys=True)) + return 0 + + print("AKMS global vault") + print(f" path: {vault}") + if not exists: + print(" status: not present") + print() + print(" No vault is installed. Install one with:") + print(" akms vault install ") + return 0 + print(f" status: {md} node file(s), {schema} declaring akms_schema") + if md == 0: + print() + print(" The vault is empty. Install one with:") + print(" akms vault install ") + return 0 + + +def cmd_vault_install(args: argparse.Namespace) -> int: + """Install a vault into the resolved global vault directory.""" + from akms.graph.build_graph import resolve_global_vault + + source = args.source or DEFAULT_VAULT_SOURCE + if not source: + print( + "error: no vault source given.\n" + "\n" + "Pass a source explicitly — a directory, a .tar.gz, or an https\n" + "URL to a released vault archive:\n" + "\n" + " akms vault install ./my-vault\n" + " akms vault install https://example.org/vault-v1.0.0.tar.gz\n", + file=sys.stderr, + ) + return 2 + + dest = Path(args.dest).expanduser() if args.dest else resolve_global_vault() + + if dest.is_dir(): + existing_md, _ = _count_nodes(dest) + if existing_md and not args.force: + print( + f"error: {dest} already holds {existing_md} node file(s).\n" + "\n" + "Automated AKMS operations treat the global vault as read-only,\n" + "so this command will not replace one you already have. Re-run\n" + "with --force to replace it, or --dest to install elsewhere.", + file=sys.stderr, + ) + return 1 + + try: + with tempfile.TemporaryDirectory() as td: + workdir = Path(td) + content = _fetch(source, workdir) + + md, schema = _count_nodes(content) + if md == 0: + raise VaultInstallError( + f"{source!r} contains no node markdown files; refusing to " + "install it as a vault" + ) + if schema == 0: + raise VaultInstallError( + f"{source!r} has {md} markdown file(s) but none declare " + "`akms_schema`; this does not look like an AKMS vault" + ) + + # Stage beside the destination and swap, so an interrupted install + # cannot leave a half-written vault where a working one used to be. + dest.parent.mkdir(parents=True, exist_ok=True) + incoming = dest.parent / f".{dest.name}.incoming" + if incoming.exists(): + shutil.rmtree(incoming) + # macOS `tar` writes AppleDouble `._name` companions beside every + # file, and they extract as real files ending in `.md`. Left in, + # they land in the vault and the graph compiler tries to parse + # binary resource-fork data as v2 nodes. Same reasoning for + # `.DS_Store`, which had already reached the published wheel once. + shutil.copytree( + content, + incoming, + ignore=shutil.ignore_patterns("._*", ".DS_Store", "__pycache__"), + ) + + previous = dest.parent / f".{dest.name}.previous" + if dest.exists(): + if previous.exists(): + shutil.rmtree(previous) + dest.rename(previous) + incoming.rename(dest) + if previous.exists(): + shutil.rmtree(previous) + except VaultInstallError as exc: + print(f"error: {exc}", file=sys.stderr) + return 1 + + result = {"vault": str(dest), "source": source, "nodes": md} + if args.json: + print(json.dumps(result, indent=2, sort_keys=True)) + else: + print(f"Installed {md} node file(s) into {dest}") + print(f" source: {source}") + print() + print("Verify with: akms vault status") + return 0 + + +def register_vault_commands(subparsers: argparse._SubParsersAction) -> None: + """Register the ``vault`` command group on the root parser.""" + vault = subparsers.add_parser( + "vault", + help="Inspect or install the global node vault", + description=( + "The node corpus is distributed separately from the akms package. " + "These commands report where AKMS looks for it and install one." + ), + ) + vault_sub = vault.add_subparsers(dest="vault_command") + + status = vault_sub.add_parser( + "status", + help="Show where the global vault resolves and what it holds", + ) + status.add_argument( + "--vault", + help="Inspect this path instead of the resolved global vault", + ) + status.add_argument("--json", action="store_true", help="Emit JSON") + status.set_defaults(func=cmd_vault_status) + + install = vault_sub.add_parser( + "install", + help="Install a vault into the global vault directory", + description=( + "Accepts a local directory, a local .tar.gz, or an https URL to a " + "released vault archive. Refuses to replace a vault that already " + "holds nodes unless --force is given." + ), + ) + install.add_argument( + "source", + nargs="?", + help="Directory, .tar.gz, or https URL holding the vault", + ) + install.add_argument( + "--dest", + help="Install here instead of the resolved global vault", + ) + install.add_argument( + "--force", + action="store_true", + help="Replace an existing non-empty vault", + ) + install.add_argument("--json", action="store_true", help="Emit JSON") + install.set_defaults(func=cmd_vault_install) + + def _require_subcommand(args: argparse.Namespace) -> int: + vault.print_help() + return 2 + + vault.set_defaults(func=_require_subcommand) diff --git a/packages/akms/tests/akms/test_seed_integration.py b/packages/akms/tests/akms/test_seed_integration.py index 8cff155..72823ee 100644 --- a/packages/akms/tests/akms/test_seed_integration.py +++ b/packages/akms/tests/akms/test_seed_integration.py @@ -24,11 +24,25 @@ from akms.schema.validators import parse_node_frontmatter # ── Path to seed data ──────────────────────────────────────────────── -# The public repo ships no separate ``seed/`` tree: ``src/akms/_bundled`` -# IS the canonical bundled corpus. These tests run against it directly. -SEED_DIR = Path(__file__).resolve().parents[2] / "src" / "akms" / "_bundled" -SEED_NODES_DIR = SEED_DIR / "global_nodes" -SEED_QMD_DIR = SEED_DIR / "qmd" +# The node corpus no longer ships inside the wheel — it is distributed as its +# own vault, because nothing in the runtime ever resolved to the bundled copy +# (``resolve_global_vault`` has four precedence levels and none of them is the +# package directory), and it accounted for roughly two thirds of the wheel. +# +# What remains here is a pinned fixture: the six ``skill-*`` nodes these tests +# assert over, plus the closure of every node their edges target and every +# ``content_ref`` payload involved — 52 nodes, self-consistent, no dangling +# edges. It lives under ``tests/`` so it is not packaged, and it keeps the +# compiler, overlay and determinism tests running against realistic node data +# rather than synthetic stubs. +# +# Corpus-wide QA — every node in the published vault validating, ids unique +# across the whole set — belongs with the vault, not here. +_PKG_ROOT = Path(__file__).resolve().parents[2] +SEED_NODES_DIR = _PKG_ROOT / "tests" / "fixtures" / "vault" + +# QMD scripts do still ship in the wheel. +SEED_QMD_DIR = _PKG_ROOT / "src" / "akms" / "_bundled" / "qmd" # ══════════════════════════════════════════════════════════════════════ diff --git a/packages/akms/tests/akms/test_vault_commands.py b/packages/akms/tests/akms/test_vault_commands.py new file mode 100644 index 0000000..981e51d --- /dev/null +++ b/packages/akms/tests/akms/test_vault_commands.py @@ -0,0 +1,179 @@ +"""Tests for ``akms vault status`` and ``akms vault install``. + +The install path writes to the user's global vault, which every other part of +AKMS treats as read-only. So the refusals matter as much as the happy path: +each one below is a case where installing anyway would either destroy a vault +the user curated or fill it with files the graph compiler cannot parse. +""" + +from __future__ import annotations + +import tarfile +from pathlib import Path + +import pytest + +from akms.cli.commands import build_parser +from akms.cli.vault_commands import _count_nodes + +pytestmark = pytest.mark.unit + + +NODE = """--- +akms_schema: v2 +id: {nid} +title: {nid} +domain: testing +tags: +- testing +status: established +confidence: 0.9 +source: human +context_size: small +reading_priority: full +--- + +Body for {nid}. +""" + + +def _make_vault(root: Path, count: int = 3) -> Path: + root.mkdir(parents=True, exist_ok=True) + for i in range(count): + (root / f"node-{i}.md").write_text( + NODE.format(nid=f"node-{i}"), encoding="utf-8" + ) + payload = root / "content" / "skill" + payload.mkdir(parents=True) + (payload / "REFERENCE.md").write_text("# payload\n", encoding="utf-8") + return root + + +def _run(argv: list[str]) -> int: + args = build_parser().parse_args(argv) + return args.func(args) + + +# ── counting ──────────────────────────────────────────────────────────── + + +def test_count_ignores_content_payloads(tmp_path: Path) -> None: + """Files under content/ are payload bodies, not nodes.""" + vault = _make_vault(tmp_path / "v", count=3) + assert _count_nodes(vault) == (3, 3) + + +def test_count_ignores_appledouble_companions(tmp_path: Path) -> None: + """macOS tar writes ``._name`` beside every file; they are not nodes. + + Regression: these extract as real files ending in ``.md``, so a vault + tarred on macOS reported double its node count and, worse, dropped binary + resource-fork data into the vault for the graph compiler to choke on. + """ + vault = _make_vault(tmp_path / "v", count=3) + (vault / "._node-0.md").write_bytes(b"\x00\x05\x16\x07AppleDouble") + (vault / ".DS_Store").write_bytes(b"\x00\x00\x00\x01Bud1") + assert _count_nodes(vault) == (3, 3) + + +# ── install ───────────────────────────────────────────────────────────── + + +def test_install_from_directory(tmp_path: Path) -> None: + src = _make_vault(tmp_path / "src", count=4) + dest = tmp_path / "vault" / "nodes" + assert _run(["vault", "install", str(src), "--dest", str(dest)]) == 0 + assert _count_nodes(dest) == (4, 4) + + +def test_install_refuses_to_replace_a_populated_vault(tmp_path: Path) -> None: + src = _make_vault(tmp_path / "src", count=2) + dest = _make_vault(tmp_path / "existing", count=5) + assert _run(["vault", "install", str(src), "--dest", str(dest)]) == 1 + # Untouched. + assert _count_nodes(dest) == (5, 5) + + +def test_force_replaces_rather_than_merges(tmp_path: Path) -> None: + src = _make_vault(tmp_path / "src", count=2) + dest = _make_vault(tmp_path / "existing", count=5) + assert _run(["vault", "install", str(src), "--dest", str(dest), "--force"]) == 0 + assert _count_nodes(dest) == (2, 2) + + +def test_install_without_a_source_is_a_usage_error(tmp_path: Path) -> None: + assert _run(["vault", "install", "--dest", str(tmp_path / "v")]) == 2 + + +def test_install_rejects_a_directory_holding_no_nodes(tmp_path: Path) -> None: + src = tmp_path / "notavault" + src.mkdir() + (src / "README.md").write_text("no frontmatter here\n", encoding="utf-8") + assert _run(["vault", "install", str(src), "--dest", str(tmp_path / "v")]) == 1 + assert not (tmp_path / "v").exists() + + +def test_install_rejects_plain_http(tmp_path: Path) -> None: + assert ( + _run( + [ + "vault", + "install", + "http://example.invalid/vault.tar.gz", + "--dest", + str(tmp_path / "v"), + ] + ) + == 1 + ) + + +def test_install_from_tarball_strips_junk(tmp_path: Path) -> None: + src = _make_vault(tmp_path / "src", count=3) + (src / "._node-0.md").write_bytes(b"\x00\x05\x16\x07AppleDouble") + archive = tmp_path / "vault.tar.gz" + with tarfile.open(archive, "w:gz") as tar: + tar.add(src, arcname="vault-v1.0.0") + + dest = tmp_path / "vault" / "nodes" + assert _run(["vault", "install", str(archive), "--dest", str(dest)]) == 0 + assert _count_nodes(dest) == (3, 3) + assert not (dest / "._node-0.md").exists() + + +def test_install_refuses_an_archive_that_escapes_the_destination( + tmp_path: Path, +) -> None: + """Path traversal in a downloaded archive must not write outside the vault.""" + outside = tmp_path / "outside.md" + src = _make_vault(tmp_path / "src", count=1) + archive = tmp_path / "evil.tar.gz" + with tarfile.open(archive, "w:gz") as tar: + tar.add(src / "node-0.md", arcname="vault/node-0.md") + info = tarfile.TarInfo(name="vault/../../escaped.md") + payload = b"akms_schema: v2\n" + info.size = len(payload) + import io + + tar.addfile(info, io.BytesIO(payload)) + + dest = tmp_path / "vault" / "nodes" + assert _run(["vault", "install", str(archive), "--dest", str(dest)]) == 1 + assert not outside.exists() + assert not (tmp_path / "escaped.md").exists() + + +# ── status ────────────────────────────────────────────────────────────── + + +def test_status_reports_a_missing_vault(tmp_path: Path, capsys) -> None: + assert _run(["vault", "status", "--vault", str(tmp_path / "nope")]) == 0 + out = capsys.readouterr().out + assert "not present" in out + assert "akms vault install" in out + + +def test_status_counts_an_installed_vault(tmp_path: Path, capsys) -> None: + vault = _make_vault(tmp_path / "v", count=7) + assert _run(["vault", "status", "--vault", str(vault), "--json"]) == 0 + assert '"markdown_files": 7' in capsys.readouterr().out diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-anisotropic-yield.md b/packages/akms/tests/fixtures/vault/cm-anisotropic-yield.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-anisotropic-yield.md rename to packages/akms/tests/fixtures/vault/cm-anisotropic-yield.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-fft-galerkin.md b/packages/akms/tests/fixtures/vault/cm-fft-galerkin.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-fft-galerkin.md rename to packages/akms/tests/fixtures/vault/cm-fft-galerkin.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-gtn-ductile-fracture.md b/packages/akms/tests/fixtures/vault/cm-gtn-ductile-fracture.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-gtn-ductile-fracture.md rename to packages/akms/tests/fixtures/vault/cm-gtn-ductile-fracture.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-kinematics-tl.md b/packages/akms/tests/fixtures/vault/cm-kinematics-tl.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-kinematics-tl.md rename to packages/akms/tests/fixtures/vault/cm-kinematics-tl.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-notation-cheatsheet.md b/packages/akms/tests/fixtures/vault/cm-notation-cheatsheet.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-notation-cheatsheet.md rename to packages/akms/tests/fixtures/vault/cm-notation-cheatsheet.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-objective-rates.md b/packages/akms/tests/fixtures/vault/cm-objective-rates.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-objective-rates.md rename to packages/akms/tests/fixtures/vault/cm-objective-rates.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-phase-field-fracture.md b/packages/akms/tests/fixtures/vault/cm-phase-field-fracture.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-phase-field-fracture.md rename to packages/akms/tests/fixtures/vault/cm-phase-field-fracture.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-solver-matrixfree.md b/packages/akms/tests/fixtures/vault/cm-solver-matrixfree.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-solver-matrixfree.md rename to packages/akms/tests/fixtures/vault/cm-solver-matrixfree.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-tensor-calculus.md b/packages/akms/tests/fixtures/vault/cm-tensor-calculus.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-tensor-calculus.md rename to packages/akms/tests/fixtures/vault/cm-tensor-calculus.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-verification.md b/packages/akms/tests/fixtures/vault/cm-verification.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-verification.md rename to packages/akms/tests/fixtures/vault/cm-verification.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/cm-viscoplastic-thermo.md b/packages/akms/tests/fixtures/vault/cm-viscoplastic-thermo.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/cm-viscoplastic-thermo.md rename to packages/akms/tests/fixtures/vault/cm-viscoplastic-thermo.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/SKILL.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/SKILL.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/SKILL.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/SKILL.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/constitutive-anisotropic-yield.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/constitutive-anisotropic-yield.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/constitutive-anisotropic-yield.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/constitutive-anisotropic-yield.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/constitutive-viscoplastic-thermo.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/constitutive-viscoplastic-thermo.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/constitutive-viscoplastic-thermo.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/constitutive-viscoplastic-thermo.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/ductile-fracture-gtn-phasefield.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/ductile-fracture-gtn-phasefield.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/ductile-fracture-gtn-phasefield.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/ductile-fracture-gtn-phasefield.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/fft-galerkin-micromechanics.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/fft-galerkin-micromechanics.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/fft-galerkin-micromechanics.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/fft-galerkin-micromechanics.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/kinematics-tl-convected.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/kinematics-tl-convected.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/kinematics-tl-convected.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/kinematics-tl-convected.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/notation-cheatsheet.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/notation-cheatsheet.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/notation-cheatsheet.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/notation-cheatsheet.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/objective-rates-integration.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/objective-rates-integration.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/objective-rates-integration.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/objective-rates-integration.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/phase-field-fracture.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/phase-field-fracture.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/phase-field-fracture.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/phase-field-fracture.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/solver-architecture-matrixfree.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/solver-architecture-matrixfree.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/solver-architecture-matrixfree.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/solver-architecture-matrixfree.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/tensor-calculus.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/tensor-calculus.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/tensor-calculus.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/tensor-calculus.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/verification-benchmarks.md b/packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/verification-benchmarks.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/computational-mechanics/reference/verification-benchmarks.md rename to packages/akms/tests/fixtures/vault/content/computational-mechanics/reference/verification-benchmarks.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/gen-test/SKILL.md b/packages/akms/tests/fixtures/vault/content/gen-test/SKILL.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/gen-test/SKILL.md rename to packages/akms/tests/fixtures/vault/content/gen-test/SKILL.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/SKILL.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/SKILL.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/SKILL.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/SKILL.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/assets/templates/TEMPLATES.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/assets/templates/TEMPLATES.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/assets/templates/TEMPLATES.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/assets/templates/TEMPLATES.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/assets/templates/mkdocs.yml b/packages/akms/tests/fixtures/vault/content/repo-documentor/assets/templates/mkdocs.yml similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/assets/templates/mkdocs.yml rename to packages/akms/tests/fixtures/vault/content/repo-documentor/assets/templates/mkdocs.yml diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/CONTRACTS.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/references/CONTRACTS.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/CONTRACTS.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/references/CONTRACTS.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/CONVENTIONS.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/references/CONVENTIONS.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/CONVENTIONS.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/references/CONVENTIONS.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/DIAGRAMS.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/references/DIAGRAMS.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/DIAGRAMS.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/references/DIAGRAMS.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/PROFILES.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/references/PROFILES.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/PROFILES.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/references/PROFILES.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/QUALITY_GATES.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/references/QUALITY_GATES.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/QUALITY_GATES.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/references/QUALITY_GATES.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/SECURITY_HARDWARE.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/references/SECURITY_HARDWARE.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/SECURITY_HARDWARE.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/references/SECURITY_HARDWARE.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/TEMPLATES.tex b/packages/akms/tests/fixtures/vault/content/repo-documentor/references/TEMPLATES.tex similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/TEMPLATES.tex rename to packages/akms/tests/fixtures/vault/content/repo-documentor/references/TEMPLATES.tex diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/VALIDATION.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/references/VALIDATION.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/VALIDATION.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/references/VALIDATION.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/WORKFLOW.md b/packages/akms/tests/fixtures/vault/content/repo-documentor/references/WORKFLOW.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/repo-documentor/references/WORKFLOW.md rename to packages/akms/tests/fixtures/vault/content/repo-documentor/references/WORKFLOW.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/shared/CONVENTIONS.md b/packages/akms/tests/fixtures/vault/content/shared/CONVENTIONS.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/shared/CONVENTIONS.md rename to packages/akms/tests/fixtures/vault/content/shared/CONVENTIONS.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/SKILL.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/SKILL.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/SKILL.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/SKILL.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/fd.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/fd.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/fd.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/fd.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/fem.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/fem.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/fem.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/fem.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/fft.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/fft.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/fft.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/fft.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/linear-solvers.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/linear-solvers.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/linear-solvers.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/linear-solvers.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/mpm.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/mpm.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/mpm.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/mpm.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/time-integration.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/time-integration.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/domains/time-integration.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/domains/time-integration.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/continuum-tensors.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/continuum-tensors.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/continuum-tensors.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/continuum-tensors.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/conventions-quickref.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/conventions-quickref.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/conventions-quickref.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/conventions-quickref.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/data-layout-and-snode.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/data-layout-and-snode.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/data-layout-and-snode.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/data-layout-and-snode.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/gotchas.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/gotchas.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/gotchas.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/gotchas.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/interop.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/interop.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/interop.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/interop.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/kernel-patterns.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/kernel-patterns.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/kernel-patterns.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/kernel-patterns.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/numerical-safeguards.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/numerical-safeguards.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/numerical-safeguards.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/numerical-safeguards.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/performance.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/performance.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/performance.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/performance.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/stress-integration.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/stress-integration.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/stress-integration.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/stress-integration.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/style-and-architecture.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/style-and-architecture.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/style-and-architecture.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/style-and-architecture.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/testing-and-validation.md b/packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/testing-and-validation.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-gpu-sim/references/testing-and-validation.md rename to packages/akms/tests/fixtures/vault/content/taichi-gpu-sim/references/testing-and-validation.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/SKILL.md b/packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/SKILL.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/SKILL.md rename to packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/SKILL.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/examples/bad-kernel-review.md b/packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/examples/bad-kernel-review.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/examples/bad-kernel-review.md rename to packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/examples/bad-kernel-review.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/examples/pr-review-template.md b/packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/examples/pr-review-template.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/examples/pr-review-template.md rename to packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/examples/pr-review-template.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/ci-cd-guidance.md b/packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/ci-cd-guidance.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/ci-cd-guidance.md rename to packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/ci-cd-guidance.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/documentation-standards.md b/packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/documentation-standards.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/documentation-standards.md rename to packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/documentation-standards.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/interface-compatibility.md b/packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/interface-compatibility.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/interface-compatibility.md rename to packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/interface-compatibility.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/review-checklist.md b/packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/review-checklist.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/review-checklist.md rename to packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/review-checklist.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/testing-verification.md b/packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/testing-verification.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/content/taichi-sim-reviewer/references/testing-verification.md rename to packages/akms/tests/fixtures/vault/content/taichi-sim-reviewer/references/testing-verification.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-asset-latex.md b/packages/akms/tests/fixtures/vault/rd-asset-latex.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-asset-latex.md rename to packages/akms/tests/fixtures/vault/rd-asset-latex.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-asset-mkdocs.md b/packages/akms/tests/fixtures/vault/rd-asset-mkdocs.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-asset-mkdocs.md rename to packages/akms/tests/fixtures/vault/rd-asset-mkdocs.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-asset-templates-md.md b/packages/akms/tests/fixtures/vault/rd-asset-templates-md.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-asset-templates-md.md rename to packages/akms/tests/fixtures/vault/rd-asset-templates-md.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-ref-contracts.md b/packages/akms/tests/fixtures/vault/rd-ref-contracts.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-ref-contracts.md rename to packages/akms/tests/fixtures/vault/rd-ref-contracts.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-ref-conventions.md b/packages/akms/tests/fixtures/vault/rd-ref-conventions.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-ref-conventions.md rename to packages/akms/tests/fixtures/vault/rd-ref-conventions.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-ref-diagrams.md b/packages/akms/tests/fixtures/vault/rd-ref-diagrams.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-ref-diagrams.md rename to packages/akms/tests/fixtures/vault/rd-ref-diagrams.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-ref-profiles.md b/packages/akms/tests/fixtures/vault/rd-ref-profiles.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-ref-profiles.md rename to packages/akms/tests/fixtures/vault/rd-ref-profiles.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-ref-quality-gates.md b/packages/akms/tests/fixtures/vault/rd-ref-quality-gates.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-ref-quality-gates.md rename to packages/akms/tests/fixtures/vault/rd-ref-quality-gates.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-ref-security-hardware.md b/packages/akms/tests/fixtures/vault/rd-ref-security-hardware.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-ref-security-hardware.md rename to packages/akms/tests/fixtures/vault/rd-ref-security-hardware.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-ref-validation.md b/packages/akms/tests/fixtures/vault/rd-ref-validation.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-ref-validation.md rename to packages/akms/tests/fixtures/vault/rd-ref-validation.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/rd-ref-workflow.md b/packages/akms/tests/fixtures/vault/rd-ref-workflow.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/rd-ref-workflow.md rename to packages/akms/tests/fixtures/vault/rd-ref-workflow.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/skill-computational-mechanics.md b/packages/akms/tests/fixtures/vault/skill-computational-mechanics.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/skill-computational-mechanics.md rename to packages/akms/tests/fixtures/vault/skill-computational-mechanics.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/skill-gen-test.md b/packages/akms/tests/fixtures/vault/skill-gen-test.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/skill-gen-test.md rename to packages/akms/tests/fixtures/vault/skill-gen-test.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/skill-repo-documentor.md b/packages/akms/tests/fixtures/vault/skill-repo-documentor.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/skill-repo-documentor.md rename to packages/akms/tests/fixtures/vault/skill-repo-documentor.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/skill-shared-conventions.md b/packages/akms/tests/fixtures/vault/skill-shared-conventions.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/skill-shared-conventions.md rename to packages/akms/tests/fixtures/vault/skill-shared-conventions.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/skill-taichi-gpu-sim.md b/packages/akms/tests/fixtures/vault/skill-taichi-gpu-sim.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/skill-taichi-gpu-sim.md rename to packages/akms/tests/fixtures/vault/skill-taichi-gpu-sim.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/skill-taichi-sim-reviewer.md b/packages/akms/tests/fixtures/vault/skill-taichi-sim-reviewer.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/skill-taichi-sim-reviewer.md rename to packages/akms/tests/fixtures/vault/skill-taichi-sim-reviewer.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-dom-fd.md b/packages/akms/tests/fixtures/vault/tgs-dom-fd.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-dom-fd.md rename to packages/akms/tests/fixtures/vault/tgs-dom-fd.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-dom-fem.md b/packages/akms/tests/fixtures/vault/tgs-dom-fem.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-dom-fem.md rename to packages/akms/tests/fixtures/vault/tgs-dom-fem.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-dom-fft.md b/packages/akms/tests/fixtures/vault/tgs-dom-fft.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-dom-fft.md rename to packages/akms/tests/fixtures/vault/tgs-dom-fft.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-dom-linear-solvers.md b/packages/akms/tests/fixtures/vault/tgs-dom-linear-solvers.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-dom-linear-solvers.md rename to packages/akms/tests/fixtures/vault/tgs-dom-linear-solvers.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-dom-mpm.md b/packages/akms/tests/fixtures/vault/tgs-dom-mpm.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-dom-mpm.md rename to packages/akms/tests/fixtures/vault/tgs-dom-mpm.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-dom-time-integration.md b/packages/akms/tests/fixtures/vault/tgs-dom-time-integration.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-dom-time-integration.md rename to packages/akms/tests/fixtures/vault/tgs-dom-time-integration.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-continuum-tensors.md b/packages/akms/tests/fixtures/vault/tgs-ref-continuum-tensors.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-continuum-tensors.md rename to packages/akms/tests/fixtures/vault/tgs-ref-continuum-tensors.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-conventions-quickref.md b/packages/akms/tests/fixtures/vault/tgs-ref-conventions-quickref.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-conventions-quickref.md rename to packages/akms/tests/fixtures/vault/tgs-ref-conventions-quickref.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-data-layout.md b/packages/akms/tests/fixtures/vault/tgs-ref-data-layout.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-data-layout.md rename to packages/akms/tests/fixtures/vault/tgs-ref-data-layout.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-gotchas.md b/packages/akms/tests/fixtures/vault/tgs-ref-gotchas.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-gotchas.md rename to packages/akms/tests/fixtures/vault/tgs-ref-gotchas.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-interop.md b/packages/akms/tests/fixtures/vault/tgs-ref-interop.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-interop.md rename to packages/akms/tests/fixtures/vault/tgs-ref-interop.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-kernel-patterns.md b/packages/akms/tests/fixtures/vault/tgs-ref-kernel-patterns.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-kernel-patterns.md rename to packages/akms/tests/fixtures/vault/tgs-ref-kernel-patterns.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-numerical-safeguards.md b/packages/akms/tests/fixtures/vault/tgs-ref-numerical-safeguards.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-numerical-safeguards.md rename to packages/akms/tests/fixtures/vault/tgs-ref-numerical-safeguards.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-performance.md b/packages/akms/tests/fixtures/vault/tgs-ref-performance.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-performance.md rename to packages/akms/tests/fixtures/vault/tgs-ref-performance.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-stress-integration.md b/packages/akms/tests/fixtures/vault/tgs-ref-stress-integration.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-stress-integration.md rename to packages/akms/tests/fixtures/vault/tgs-ref-stress-integration.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-style-architecture.md b/packages/akms/tests/fixtures/vault/tgs-ref-style-architecture.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-style-architecture.md rename to packages/akms/tests/fixtures/vault/tgs-ref-style-architecture.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tgs-ref-testing-validation.md b/packages/akms/tests/fixtures/vault/tgs-ref-testing-validation.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tgs-ref-testing-validation.md rename to packages/akms/tests/fixtures/vault/tgs-ref-testing-validation.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tsr-ex-bad-kernel-review.md b/packages/akms/tests/fixtures/vault/tsr-ex-bad-kernel-review.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tsr-ex-bad-kernel-review.md rename to packages/akms/tests/fixtures/vault/tsr-ex-bad-kernel-review.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tsr-ex-pr-template.md b/packages/akms/tests/fixtures/vault/tsr-ex-pr-template.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tsr-ex-pr-template.md rename to packages/akms/tests/fixtures/vault/tsr-ex-pr-template.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tsr-ref-ci-cd.md b/packages/akms/tests/fixtures/vault/tsr-ref-ci-cd.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tsr-ref-ci-cd.md rename to packages/akms/tests/fixtures/vault/tsr-ref-ci-cd.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tsr-ref-documentation-standards.md b/packages/akms/tests/fixtures/vault/tsr-ref-documentation-standards.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tsr-ref-documentation-standards.md rename to packages/akms/tests/fixtures/vault/tsr-ref-documentation-standards.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tsr-ref-interface-compatibility.md b/packages/akms/tests/fixtures/vault/tsr-ref-interface-compatibility.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tsr-ref-interface-compatibility.md rename to packages/akms/tests/fixtures/vault/tsr-ref-interface-compatibility.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tsr-ref-review-checklist.md b/packages/akms/tests/fixtures/vault/tsr-ref-review-checklist.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tsr-ref-review-checklist.md rename to packages/akms/tests/fixtures/vault/tsr-ref-review-checklist.md diff --git a/packages/akms/src/akms/_bundled/global_nodes/tsr-ref-testing-verification.md b/packages/akms/tests/fixtures/vault/tsr-ref-testing-verification.md similarity index 100% rename from packages/akms/src/akms/_bundled/global_nodes/tsr-ref-testing-verification.md rename to packages/akms/tests/fixtures/vault/tsr-ref-testing-verification.md From 14a5ef08f129ea34c619afe7dc6d773f9cd01b9e Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 16:59:18 +0300 Subject: [PATCH 02/10] docs: fix package paths that do not exist, and document install honestly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Paths.** The docs referenced `Packages/AKMS`, `Packages/AKMS_nodes_gen` and friends 37 times across 14 files. git tracks `packages/akms` and `packages/akms_nodes_gen` — lowercase. Every one of those commands resolves on a case-insensitive macOS filesystem and fails outright on Linux, including the first command on the installation page. Rewritten and each resulting path checked against the tree. **Installation.** The page opened with "the documentation currently assumes a repository checkout rather than a PyPI release", which stopped being true when 0.3.0 published. It now leads with `pip install akms` and keeps the source checkout as the contributor path. It also claimed the root workspace path-sources `mechdsl-core` and `algo2code` from a sibling `../MechDSL` checkout, so a full sync "requires that layout". That is a private-repo detail; the public root declares four workspace members and nothing else, which is why CI runs `uv sync --locked --all-packages --all-extras --all-groups` on every push. The warning could only have deterred people from a command that works. **The vault.** The page told a new user to `mkdir -p ~/.claude/akms/nodes` and never said where nodes come from, so every fresh install has had an empty vault. It now explains that vaults are distributed separately and documents `akms vault status` and `akms vault install`. **Code mirrors.** Made explicit that a mirror is generated from your own repository rather than shipped — it is build output, and nothing arrives pre-populated. The `repo2md` provider now says plainly that it needs the external `repo-wiki` executable, which AKMS does not install, that `legacy` is the in-process default requiring nothing, and that because `mirror.fallback_on_error` defaults to false, configuring repo2md without the binary fails loudly rather than silently reverting. Verified on a strict build. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- docs/getting-started/akms/installation.md | 105 ++++++++++++------ docs/getting-started/nodes-gen/install.md | 8 +- docs/reference/akms/dev-guide/setup.md | 4 +- docs/reference/akms/dev-guide/testing.md | 10 +- .../user-guide/failure_memory_public_api.md | 4 +- .../akms/user-guide/mirror_providers.md | 18 ++- .../nodes-gen/batch-picker/configuration.md | 4 +- .../nodes-gen/batch-picker/data-sources.md | 2 +- docs/reference/nodes-gen/development.md | 10 +- .../nodes-gen/tools/akms-node-promote.md | 2 +- .../tools/extract-framework-nodes.md | 4 +- .../tools/generate-nodes-pipeline.md | 4 +- docs/reference/nodes-gen/tools/nlm-batch.md | 2 +- .../nodes-gen/tools/validate-nodes.md | 10 +- 14 files changed, 119 insertions(+), 68 deletions(-) diff --git a/docs/getting-started/akms/installation.md b/docs/getting-started/akms/installation.md index f094184..324d8a2 100644 --- a/docs/getting-started/akms/installation.md +++ b/docs/getting-started/akms/installation.md @@ -12,58 +12,88 @@ Use Python 3.12 for a complete-workspace environment. -## Source checkout +## Install from PyPI -The documentation currently assumes a repository checkout rather than a PyPI -release. +```bash +pip install akms +akms --help +``` -### Core package only +That is the deterministic core: graph compilation, task-context resolution, +loadouts and the CLI. The companion packages are independent installs: ```bash -uv sync --project Packages/AKMS --all-extras --all-groups -uv run --project Packages/AKMS akms --help +pip install akms-learn # learning-packet compiler +pip install akms-nodes-gen # node generation and validation tooling +pip install akms-failure-memory # project-owned failure memory ``` -### Complete workspace +The optional embedded coding-agent runtime is an extra rather than a separate +package: ```bash -uv sync --all-packages --all-extras --all-groups +pip install "akms[orchestration]" ``` -The root workspace path-sources `mechdsl-core` and `algo2code` from the sibling -checkout `../MechDSL`. A complete all-extras sync therefore requires that -layout. Use the package-scoped command for core work when the sibling adapter -repository is absent. - ## Global vault -The default global node directory is: - -```text -~/.claude/akms/nodes/ -``` - -Vault resolution precedence is: +AKMS compiles a graph from two inputs: nodes local to your repository, and a +**global vault** of shared nodes. The vault is a directory of Markdown nodes +resolved in this order: 1. Explicit Python argument 2. `AKMS_GLOBAL_VAULT` 3. `global_vault` in `knowledge/graph/propagation_config.yaml` -4. The default above +4. `~/.claude/akms/nodes/` + +**No vault ships inside the `akms` package.** A vault is content with its own +life cycle — nodes are added, corrected and forked far more often than code is +released — so vaults are distributed separately and installed deliberately. +Check what you have: + +```bash +akms vault status +``` -The graph compiler tolerates a missing or empty vault. Create it manually when -you intend to use shared nodes: +To install one from a directory, a `.tar.gz`, or an https URL to a released +vault archive: ```bash -mkdir -p ~/.claude/akms/nodes +akms vault install ./my-vault +akms vault install https://example.org/vault-v1.0.0.tar.gz ``` -Automated AKMS operations treat this directory as read-only. +`vault install` refuses to replace a vault that already holds nodes unless you +pass `--force`, and refuses a source whose Markdown declares no `akms_schema`. +Use `--dest` to install somewhere other than the resolved location. -## Verify the core CLI +The graph compiler tolerates a missing or empty vault, so AKMS is usable +against repository-local nodes alone. Aside from `vault install`, which you run +yourself, automated AKMS operations treat this directory as read-only. + +## Source checkout + +For contributing, or to run against unreleased code: + +```bash +git clone https://github.com/CEmM2/AKMS +cd AKMS +uv sync --all-packages --all-extras --all-groups +``` + +To work on the core package alone: + +```bash +uv sync --project packages/akms --all-extras --all-groups +uv run --project packages/akms akms --help +``` + +## Verify ```bash -uv run --project Packages/AKMS akms --help -uv run --project Packages/AKMS akms status --repo . +akms --help +akms status --repo . +akms vault status ``` `status` reports the graph inputs it can find; it does not require a non-empty @@ -71,11 +101,16 @@ global vault. ## Optional external tools -- `qmd` is an external search binary. The core package pins the expected version - in package metadata and falls back through its wrapper when unavailable. -- `repo2md` is invoked only through its configured CLI contract by the - `repo2md` mirror provider. -- `nlm` is an external NotebookLM CLI used by selected node-generation and +None of these are installed by AKMS, and none are required. + +- **`qmd`** — an external search binary used to rank node and mirror content. + The wrappers detect it and fall back to `grep` when it is absent. +- **`repo-wiki`** — required only by the `repo2md` mirror provider. Code mirrors + default to the `legacy` provider, an in-process Python AST projection that + needs nothing external, so this matters only if you explicitly configure + `mirror.provider: repo2md`. See + [Code-mirror providers](../../reference/akms/user-guide/mirror_providers.md). +- **`nlm`** — an external NotebookLM CLI used by selected node-generation and learning-provider workflows. -- Claude/Codex CLI executables are required only for their corresponding - optional pipeline backends. +- **Claude / Codex CLI** — required only by their corresponding optional + pipeline backends. diff --git a/docs/getting-started/nodes-gen/install.md b/docs/getting-started/nodes-gen/install.md index 10362ef..3516d76 100644 --- a/docs/getting-started/nodes-gen/install.md +++ b/docs/getting-started/nodes-gen/install.md @@ -23,7 +23,7 @@ From the AKMS repo root: ```bash # 1. Resolve and install dependencies for the AKMS_nodes_gen workspace member -uv sync --project Packages/AKMS_nodes_gen +uv sync --project packages/akms_nodes_gen ``` `uv sync` builds the editable install and pulls in `fastapi`, `uvicorn`, @@ -34,7 +34,7 @@ uv sync --project Packages/AKMS_nodes_gen If you want the `akms-pick` command available from anywhere on your `PATH`: ```bash -uv tool install --editable Packages/AKMS_nodes_gen +uv tool install --editable packages/akms_nodes_gen ``` That installs two equivalent executables — `akms-pick` (short) and @@ -45,7 +45,7 @@ That installs two equivalent executables — `akms-pick` (short) and === "After uv sync (per-project)" ```bash - uv --project Packages/AKMS_nodes_gen run akms-pick + uv --project packages/akms_nodes_gen run akms-pick ``` === "After uv tool install (global)" @@ -57,7 +57,7 @@ That installs two equivalent executables — `akms-pick` (short) and === "Module-style fallback" ```bash - uv --project Packages/AKMS_nodes_gen run \ + uv --project packages/akms_nodes_gen run \ python -m akms_nodes_gen.batch_picker ``` diff --git a/docs/reference/akms/dev-guide/setup.md b/docs/reference/akms/dev-guide/setup.md index 3bd0907..9f7a17f 100644 --- a/docs/reference/akms/dev-guide/setup.md +++ b/docs/reference/akms/dev-guide/setup.md @@ -13,8 +13,8 @@ ```bash git clone cd AKMS -uv sync --project Packages/AKMS --all-extras --all-groups -uv run --project Packages/AKMS pytest Packages/AKMS/tests/akms -q +uv sync --project packages/akms --all-extras --all-groups +uv run --project packages/akms pytest packages/akms/tests/akms -q ``` ## Whole workspace diff --git a/docs/reference/akms/dev-guide/testing.md b/docs/reference/akms/dev-guide/testing.md index 984ca31..daf00b3 100644 --- a/docs/reference/akms/dev-guide/testing.md +++ b/docs/reference/akms/dev-guide/testing.md @@ -7,9 +7,9 @@ useful test, which is an oddly self-defeating quality metric. ## Core ```bash -uv run --project Packages/AKMS pytest Packages/AKMS/tests/akms -q -uv run --project Packages/AKMS pytest Packages/AKMS/tests/e2e -q -uv run --project Packages/AKMS pytest Packages/AKMS/tests/plan_tests -q +uv run --project packages/akms pytest packages/akms/tests/akms -q +uv run --project packages/akms pytest packages/akms/tests/e2e -q +uv run --project packages/akms pytest packages/akms/tests/plan_tests -q ``` Markers declared by the core package include `unit`, `integration`, @@ -31,8 +31,8 @@ uv run --project packages/akms_learn pytest \ ## Node generation ```bash -uv run --project Packages/AKMS_nodes_gen pytest \ - Packages/AKMS_nodes_gen/tests -q +uv run --project packages/akms_nodes_gen pytest \ + packages/akms_nodes_gen/tests -q ``` ## compmech reference pack diff --git a/docs/reference/akms/user-guide/failure_memory_public_api.md b/docs/reference/akms/user-guide/failure_memory_public_api.md index 0b875d2..f5cbee9 100644 --- a/docs/reference/akms/user-guide/failure_memory_public_api.md +++ b/docs/reference/akms/user-guide/failure_memory_public_api.md @@ -4,7 +4,7 @@ The optional `akms-failure-memory` package may depend only on documented public AKMS contracts. The machine-readable pin lives at: ```text -Packages/AKMS/release/failure_memory_public_api_pin.json +packages/akms/release/failure_memory_public_api_pin.json ``` ## Permitted surface @@ -36,5 +36,5 @@ test stops complaining. ## Stability test ```bash -uv run pytest Packages/AKMS/tests/akms/test_failure_memory_public_api_pin.py -q +uv run pytest packages/akms/tests/akms/test_failure_memory_public_api_pin.py -q ``` diff --git a/docs/reference/akms/user-guide/mirror_providers.md b/docs/reference/akms/user-guide/mirror_providers.md index 7f15546..ff1157b 100644 --- a/docs/reference/akms/user-guide/mirror_providers.md +++ b/docs/reference/akms/user-guide/mirror_providers.md @@ -4,6 +4,12 @@ AKMS projects repository source into `knowledge/code-mirror/` for exact path resolution, search, and review context. Projection is pluggable; graph and loadout semantics remain in AKMS core. +A code mirror is **generated from your own repository**, not shipped with AKMS. +Nothing arrives pre-populated and there is nothing to download: you produce one +with `akms generate-mirror` and refresh it as the source changes. A mirror is +build output, and like build output it belongs to the tree it was projected +from. + ## Defaults | Setting | Default | Meaning | @@ -35,6 +41,9 @@ The command is an argv prefix, not a shell string. ## `legacy` +The default, and the only provider that works out of the box — it is +in-process and needs nothing installed beyond `akms` itself. + - Python-only AST projection - In-process implementation - Changed-file selection by default @@ -42,11 +51,18 @@ The command is an argv prefix, not a shell string. ## `repo2md` +Requires the external `repo-wiki` executable, which **AKMS does not install**. +It is registered lazily and invoked only when you configure +`mirror.provider: repo2md`, so its absence costs nothing until then. Because +`mirror.fallback_on_error` defaults to `false`, configuring this provider +without the binary present fails loudly rather than silently reverting to +`legacy` — set that flag to `true` if you would rather it fell back. + - Invokes `repo-wiki export-akms` with `shell=False` - Does not import repo2md as a Python package - Validates export schema, AKMS v2 frontmatter, output containment, content/source consistency, duplicate IDs, and completeness -- Uses a pinned consumer contract under `Packages/AKMS/release/` +- Uses a pinned consumer contract under `packages/akms/release/` ## CLI diff --git a/docs/reference/nodes-gen/batch-picker/configuration.md b/docs/reference/nodes-gen/batch-picker/configuration.md index 36a8c65..8640d52 100644 --- a/docs/reference/nodes-gen/batch-picker/configuration.md +++ b/docs/reference/nodes-gen/batch-picker/configuration.md @@ -7,8 +7,8 @@ Every path is overridable via an environment variable. | Env var | Default | What it points at | |---------|---------|-------------------| -| `AKMS_REPO_ROOT` | Auto-detected (`Packages/AKMS_nodes_gen/src/akms_nodes_gen/batch_picker/config.py` walked up 5 levels) | The AKMS monorepo root — base for the other defaults | -| `AKMS_PLAN_MD` | `/Packages/AKMS_nodes_gen/generation_plan.md` | Markdown file the parser reads | +| `AKMS_REPO_ROOT` | Auto-detected (`packages/akms_nodes_gen/src/akms_nodes_gen/batch_picker/config.py` walked up 5 levels) | The AKMS monorepo root — base for the other defaults | +| `AKMS_PLAN_MD` | `/packages/akms_nodes_gen/generation_plan.md` | Markdown file the parser reads | | `AKMS_BBT_JSON` | `~/ZotSums/zsumbib.json` | BetterBibTeX export with all paper metadata + PDF paths | | `AKMS_ZOTSUMS_ROOT` | `~/ZotSums` | ZotSums Obsidian vault (Papers/, Collections/) | | `AKMS_BATCH_STATE` | `/Sources_Evals/NLM/batch_assignments.json` | Per-batch citekey assignments + NLM metadata | diff --git a/docs/reference/nodes-gen/batch-picker/data-sources.md b/docs/reference/nodes-gen/batch-picker/data-sources.md index 4656541..9e2a675 100644 --- a/docs/reference/nodes-gen/batch-picker/data-sources.md +++ b/docs/reference/nodes-gen/batch-picker/data-sources.md @@ -136,7 +136,7 @@ from a tooling perspective. ## 3. `generation_plan.md` (the batch plan) -Default: `Packages/AKMS_nodes_gen/generation_plan.md`. Override with +Default: `packages/akms_nodes_gen/generation_plan.md`. Override with `AKMS_PLAN_MD`. The parser is intentionally lenient about ordering and tolerates extra diff --git a/docs/reference/nodes-gen/development.md b/docs/reference/nodes-gen/development.md index b8fe90b..3f090b1 100644 --- a/docs/reference/nodes-gen/development.md +++ b/docs/reference/nodes-gen/development.md @@ -7,19 +7,19 @@ How to extend, test, and contribute to the package. ```bash git clone git@github.com:the AKMS repository.git cd AKMS -uv sync --project Packages/AKMS_nodes_gen +uv sync --project packages/akms_nodes_gen ``` For docs work, also pull in the `docs` group: ```bash -uv sync --project Packages/AKMS_nodes_gen --group docs +uv sync --project packages/akms_nodes_gen --group docs ``` ## Running the docs locally ```bash -uv --project Packages/AKMS_nodes_gen run --group docs mkdocs serve -f Packages/AKMS_nodes_gen/mkdocs.yml +uv --project packages/akms_nodes_gen run --group docs mkdocs serve -f packages/akms_nodes_gen/mkdocs.yml ``` Opens at `http://127.0.0.1:8000/`. Live-reloads on save. @@ -27,7 +27,7 @@ Opens at `http://127.0.0.1:8000/`. Live-reloads on save. ## Running the picker in dev mode ```bash -uv --project Packages/AKMS_nodes_gen run akms-pick --reload +uv --project packages/akms_nodes_gen run akms-pick --reload ``` `--reload` enables uvicorn's file watcher; saving any `.py` under the @@ -61,7 +61,7 @@ There is no `tests/` folder yet — adding one would be an easy win. The shape that fits this codebase: ``` -Packages/AKMS_nodes_gen/tests/ +packages/akms_nodes_gen/tests/ └── batch_picker/ ├── conftest.py # shared fixtures (Paths, fake catalog) ├── test_plan_parser.py # parse_plan against known plans + edge cases diff --git a/docs/reference/nodes-gen/tools/akms-node-promote.md b/docs/reference/nodes-gen/tools/akms-node-promote.md index e9f1464..c185597 100644 --- a/docs/reference/nodes-gen/tools/akms-node-promote.md +++ b/docs/reference/nodes-gen/tools/akms-node-promote.md @@ -5,7 +5,7 @@ vault (`~/.claude/akms/nodes/`) with domain-based subdirectory nesting. ## Location -`Packages/AKMS_nodes_gen/src/akms_nodes_gen/akms_node_promote.py` +`packages/akms_nodes_gen/src/akms_nodes_gen/akms_node_promote.py` ## Run it diff --git a/docs/reference/nodes-gen/tools/extract-framework-nodes.md b/docs/reference/nodes-gen/tools/extract-framework-nodes.md index ec09b32..6046c90 100644 --- a/docs/reference/nodes-gen/tools/extract-framework-nodes.md +++ b/docs/reference/nodes-gen/tools/extract-framework-nodes.md @@ -8,12 +8,12 @@ distilled content. ## Location -`Packages/AKMS_nodes_gen/extract_framework_nodes.py` +`packages/akms_nodes_gen/extract_framework_nodes.py` ## Run it ```bash -python Packages/AKMS_nodes_gen/extract_framework_nodes.py \ +python packages/akms_nodes_gen/extract_framework_nodes.py \ [--manifest manifest.yaml] ``` diff --git a/docs/reference/nodes-gen/tools/generate-nodes-pipeline.md b/docs/reference/nodes-gen/tools/generate-nodes-pipeline.md index 1eba201..e91f397 100644 --- a/docs/reference/nodes-gen/tools/generate-nodes-pipeline.md +++ b/docs/reference/nodes-gen/tools/generate-nodes-pipeline.md @@ -7,7 +7,7 @@ v2 schema, and writes clean Markdown files. ## Location -`Packages/AKMS_nodes_gen/src/akms_nodes_gen/generate_nodes_pipeline.py` +`packages/akms_nodes_gen/src/akms_nodes_gen/generate_nodes_pipeline.py` ## Run it @@ -49,7 +49,7 @@ python -m akms_nodes_gen.generate_nodes_pipeline \ This is the **automated** alternative to running `node-gen-invoker` from the AKMS skill. The Batch Picker writes its plan JSONs in a different shape (consumed by the skill); `generate_nodes_pipeline.py` consumes -inventory JSONs from `Packages/AKMS_nodes_gen/Inventory_files/` directly. +inventory JSONs from `packages/akms_nodes_gen/Inventory_files/` directly. ## See also diff --git a/docs/reference/nodes-gen/tools/nlm-batch.md b/docs/reference/nodes-gen/tools/nlm-batch.md index ee57740..1bfc13b 100644 --- a/docs/reference/nodes-gen/tools/nlm-batch.md +++ b/docs/reference/nodes-gen/tools/nlm-batch.md @@ -8,7 +8,7 @@ NotebookLM owns source-grounded synthesis from the selected batch notebook. ## Location -`Packages/AKMS_nodes_gen/src/akms_nodes_gen/nlm_batch.py` +`packages/akms_nodes_gen/src/akms_nodes_gen/nlm_batch.py` ## When to use it diff --git a/docs/reference/nodes-gen/tools/validate-nodes.md b/docs/reference/nodes-gen/tools/validate-nodes.md index 43094f4..5e22ab9 100644 --- a/docs/reference/nodes-gen/tools/validate-nodes.md +++ b/docs/reference/nodes-gen/tools/validate-nodes.md @@ -6,22 +6,22 @@ validation query and recording the per-node JSON report. ## Location -`Packages/AKMS_nodes_gen/validate_nodes.py` +`packages/akms_nodes_gen/validate_nodes.py` ## Run it ```bash # Validate every node -python Packages/AKMS_nodes_gen/validate_nodes.py +python packages/akms_nodes_gen/validate_nodes.py # Limit to one batch -python Packages/AKMS_nodes_gen/validate_nodes.py --batch R7_B2 +python packages/akms_nodes_gen/validate_nodes.py --batch R7_B2 # Preview without submitting -python Packages/AKMS_nodes_gen/validate_nodes.py --dry-run +python packages/akms_nodes_gen/validate_nodes.py --dry-run # Concurrency knob -python Packages/AKMS_nodes_gen/validate_nodes.py --concurrency 4 +python packages/akms_nodes_gen/validate_nodes.py --concurrency 4 ``` ## What it does From 3604a1baee376e55531405c2cde0c6d804b59f7a Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 17:14:04 +0300 Subject: [PATCH 03/10] fix(vault): install vault content, not the repository around it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A vault distributed as a git repository carries a README, a licence and CI configuration. Copying those into the vault is not merely untidy: the graph compiler treats any markdown in the vault lacking ``akms_schema`` as a schema error and re-raises it regardless of strictness, so a README in the vault makes every later build fail with SchemaValidationError. Every GitHub repository has one, and so does Packages/Nodes_Vault — the corpus this vault is generated from. Verified by installing a repository-shaped source and watching build_graph refuse it. The fix belongs in the installer rather than in a layout rule vault authors have to remember. ``vault install`` now copies what a vault *is* — files declaring ``akms_schema``, plus the ``content/`` payload tree they address through ``content_ref`` — and reports the top-level names it left behind instead of discarding them silently. That single pass also subsumes the dotfile filtering, so AppleDouble ``._name`` companions and ``.DS_Store`` never reach the vault either. Verified end to end: a source carrying README.md, LICENSE and .github/ installs 52 nodes, leaves the furniture behind, names it in the output, and compiles to a 52-node, 165-edge graph. 769 tests pass; ruff clean. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- packages/akms/src/akms/cli/vault_commands.py | 84 +++++++++++++++---- .../akms/tests/akms/test_vault_commands.py | 36 ++++++++ 2 files changed, 106 insertions(+), 14 deletions(-) diff --git a/packages/akms/src/akms/cli/vault_commands.py b/packages/akms/src/akms/cli/vault_commands.py index b4fbff2..0508b78 100644 --- a/packages/akms/src/akms/cli/vault_commands.py +++ b/packages/akms/src/akms/cli/vault_commands.py @@ -58,6 +58,56 @@ def _count_nodes(directory: Path) -> tuple[int, int]: return md, schema +def _is_node(path: Path) -> bool: + """Does this file look like a v2 node rather than repository furniture?""" + if path.suffix != ".md" or path.name.startswith("."): + return False + try: + return ( + "akms_schema" in path.read_text(encoding="utf-8", errors="replace")[:2048] + ) + except OSError: + return False + + +def _install_tree(src: Path, dest: Path) -> tuple[int, list[str]]: + """Copy vault content from ``src`` to ``dest``, leaving furniture behind. + + A vault distributed as a git repository carries a README, a licence, CI + configuration — and the graph compiler treats *any* markdown in the vault + that lacks ``akms_schema`` as a schema error and re-raises it regardless of + strictness. So installing a repository wholesale makes every subsequent + build fail on its own README. Rather than push that onto vault authors as a + layout rule to remember, the installer copies only what a vault is: nodes + that declare ``akms_schema``, and the ``content/`` payload tree they + address through ``content_ref``. + + Returns the node count and the top-level names that were left behind, so + the caller can say what it skipped instead of silently discarding things. + """ + nodes = 0 + skipped: set[str] = set() + for path in sorted(src.rglob("*")): + if not path.is_file(): + continue + rel = path.relative_to(src) + if any(part.startswith(".") for part in rel.parts): + continue + if "content" in rel.parts[:-1]: + target = dest / rel + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(path, target) + continue + if _is_node(path): + target = dest / rel + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(path, target) + nodes += 1 + else: + skipped.add(rel.parts[0]) + return nodes, sorted(skipped) + + def _safe_extract(archive: Path, dest: Path) -> None: """Extract a tar archive, refusing members that escape ``dest``. @@ -198,20 +248,22 @@ def cmd_vault_install(args: argparse.Namespace) -> int: ) return 1 + md = 0 + skipped: list[str] = [] try: with tempfile.TemporaryDirectory() as td: workdir = Path(td) content = _fetch(source, workdir) - md, schema = _count_nodes(content) - if md == 0: + _total, schema = _count_nodes(content) + if _total == 0: raise VaultInstallError( f"{source!r} contains no node markdown files; refusing to " "install it as a vault" ) if schema == 0: raise VaultInstallError( - f"{source!r} has {md} markdown file(s) but none declare " + f"{source!r} has {_total} markdown file(s) but none declare " "`akms_schema`; this does not look like an AKMS vault" ) @@ -221,16 +273,13 @@ def cmd_vault_install(args: argparse.Namespace) -> int: incoming = dest.parent / f".{dest.name}.incoming" if incoming.exists(): shutil.rmtree(incoming) - # macOS `tar` writes AppleDouble `._name` companions beside every - # file, and they extract as real files ending in `.md`. Left in, - # they land in the vault and the graph compiler tries to parse - # binary resource-fork data as v2 nodes. Same reasoning for - # `.DS_Store`, which had already reached the published wheel once. - shutil.copytree( - content, - incoming, - ignore=shutil.ignore_patterns("._*", ".DS_Store", "__pycache__"), - ) + incoming.mkdir(parents=True) + # Copies nodes and content/ payloads only. Dotfiles are excluded by + # the same pass, which also drops the AppleDouble `._name` + # companions macOS `tar` writes beside every file — they extract as + # real files ending in `.md`, and the compiler would try to parse + # resource-fork binary as a v2 node. + md, skipped = _install_tree(content, incoming) previous = dest.parent / f".{dest.name}.previous" if dest.exists(): @@ -244,12 +293,19 @@ def cmd_vault_install(args: argparse.Namespace) -> int: print(f"error: {exc}", file=sys.stderr) return 1 - result = {"vault": str(dest), "source": source, "nodes": md} + result = { + "vault": str(dest), + "source": source, + "nodes": md, + "skipped": skipped, + } if args.json: print(json.dumps(result, indent=2, sort_keys=True)) else: print(f"Installed {md} node file(s) into {dest}") print(f" source: {source}") + if skipped: + print(f" not vault content, left behind: {', '.join(skipped)}") print() print("Verify with: akms vault status") return 0 diff --git a/packages/akms/tests/akms/test_vault_commands.py b/packages/akms/tests/akms/test_vault_commands.py index 981e51d..ee5b483 100644 --- a/packages/akms/tests/akms/test_vault_commands.py +++ b/packages/akms/tests/akms/test_vault_commands.py @@ -84,6 +84,42 @@ def test_install_from_directory(tmp_path: Path) -> None: dest = tmp_path / "vault" / "nodes" assert _run(["vault", "install", str(src), "--dest", str(dest)]) == 0 assert _count_nodes(dest) == (4, 4) + # content_ref payloads travel with the nodes that address them. + assert (dest / "content" / "skill" / "REFERENCE.md").is_file() + + +def test_install_leaves_repository_furniture_behind(tmp_path: Path) -> None: + """A vault distributed as a git repo carries files that are not nodes. + + This is not tidiness. The graph compiler treats any markdown in the vault + without ``akms_schema`` as a schema error and re-raises it regardless of + strictness, so a README copied into the vault makes every later build fail. + Every GitHub repository has one. + """ + src = _make_vault(tmp_path / "src", count=3) + (src / "README.md").write_text( + "# Vault\n\nProse, no frontmatter.\n", encoding="utf-8" + ) + (src / "LICENSE").write_text("Apache-2.0\n", encoding="utf-8") + (src / ".github" / "workflows").mkdir(parents=True) + (src / ".github" / "workflows" / "ci.yml").write_text( + "name: ci\n", encoding="utf-8" + ) + + dest = tmp_path / "vault" / "nodes" + assert _run(["vault", "install", str(src), "--dest", str(dest)]) == 0 + assert _count_nodes(dest) == (3, 3) + assert not (dest / "README.md").exists() + assert not (dest / "LICENSE").exists() + assert not (dest / ".github").exists() + + +def test_install_reports_what_it_left_behind(tmp_path: Path, capsys) -> None: + src = _make_vault(tmp_path / "src", count=2) + (src / "README.md").write_text("# Vault\n", encoding="utf-8") + dest = tmp_path / "vault" / "nodes" + assert _run(["vault", "install", str(src), "--dest", str(dest), "--json"]) == 0 + assert '"README.md"' in capsys.readouterr().out def test_install_refuses_to_replace_a_populated_vault(tmp_path: Path) -> None: From 0688b2968176554cf95d912f25d1b1898f3ba59a Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 17:18:21 +0300 Subject: [PATCH 04/10] fix(vault): detect nodes structurally, not by substring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A vault's README documents the node format, so it contains the text `akms_schema` inside a fenced example. The substring test that decided what to install therefore classified the README as a node, copied it into the vault, and the graph compiler aborted every subsequent build on it — the exact failure the previous commit set out to prevent. Found by generating the real vault repository and installing it: 303 nodes instead of 302, then SchemaValidationError on README.md. Detection is now structural. The file must open with a frontmatter fence, and `akms_schema` must appear as a top-level key before that block closes. Prose and fenced examples cannot satisfy that. Verified against the generated vault: 302 nodes install, README, LICENSE and scripts/ are named as left behind, and the result compiles to a 302-node, 1045-edge graph. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- packages/akms/src/akms/cli/vault_commands.py | 45 +++++++++++++------ .../akms/tests/akms/test_vault_commands.py | 26 +++++++++++ 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/packages/akms/src/akms/cli/vault_commands.py b/packages/akms/src/akms/cli/vault_commands.py index 0508b78..6cac55d 100644 --- a/packages/akms/src/akms/cli/vault_commands.py +++ b/packages/akms/src/akms/cli/vault_commands.py @@ -34,12 +34,38 @@ class VaultInstallError(RuntimeError): """Raised when a vault cannot be fetched, validated, or installed.""" +def _declares_schema(path: Path) -> bool: + """Does this file open with frontmatter declaring ``akms_schema``? + + Deliberately structural rather than a substring search. A vault's own + README documents the node format, so it contains the text ``akms_schema`` + in a fenced example — and a plain ``"akms_schema" in text`` test classifies + that README as a node, installs it into the vault, and the graph compiler + then aborts every build on it. Found exactly that way. + + So: the file must *start* with a frontmatter fence, and the key must appear + at the top level of that block, before it closes. + """ + try: + text = path.read_text(encoding="utf-8", errors="replace") + except OSError: + return False + if not text.startswith("---"): + return False + lines = text.splitlines() + for line in lines[1:]: + if line.rstrip() in {"---", "..."}: + return False + if line.startswith("akms_schema:"): + return True + return False + + def _count_nodes(directory: Path) -> tuple[int, int]: """Return (markdown files, files that declare ``akms_schema``). - Deliberately cheap and tolerant: this is a sanity check on a downloaded - archive, not schema validation. The graph compiler does the real parsing - and reports precisely what it rejects. + A sanity check on a source tree, not schema validation. The graph compiler + does the real parsing and reports precisely what it rejects. """ md = 0 schema = 0 @@ -49,11 +75,7 @@ def _count_nodes(directory: Path) -> tuple[int, int]: if "content" in path.relative_to(directory).parts[:-1]: continue md += 1 - try: - head = path.read_text(encoding="utf-8", errors="replace")[:2048] - except OSError: - continue - if "akms_schema" in head: + if _declares_schema(path): schema += 1 return md, schema @@ -62,12 +84,7 @@ def _is_node(path: Path) -> bool: """Does this file look like a v2 node rather than repository furniture?""" if path.suffix != ".md" or path.name.startswith("."): return False - try: - return ( - "akms_schema" in path.read_text(encoding="utf-8", errors="replace")[:2048] - ) - except OSError: - return False + return _declares_schema(path) def _install_tree(src: Path, dest: Path) -> tuple[int, list[str]]: diff --git a/packages/akms/tests/akms/test_vault_commands.py b/packages/akms/tests/akms/test_vault_commands.py index ee5b483..aed8a46 100644 --- a/packages/akms/tests/akms/test_vault_commands.py +++ b/packages/akms/tests/akms/test_vault_commands.py @@ -114,6 +114,32 @@ def test_install_leaves_repository_furniture_behind(tmp_path: Path) -> None: assert not (dest / ".github").exists() +def test_a_readme_documenting_the_node_format_is_not_a_node(tmp_path: Path) -> None: + """A vault's README explains the format, so it *mentions* ``akms_schema``. + + Regression: a substring test classified such a README as a node, installed + it, and the graph compiler then aborted every build on it. The real vault + README hit this immediately. Detection has to be structural — frontmatter + fence first, key at the top level of that block. + """ + src = _make_vault(tmp_path / "src", count=3) + (src / "README.md").write_text( + "# My Vault\n\n" + "Every node declares `akms_schema` in its frontmatter:\n\n" + "```yaml\n" + "---\n" + "akms_schema: v2\n" + "id: example\n" + "---\n" + "```\n", + encoding="utf-8", + ) + dest = tmp_path / "vault" / "nodes" + assert _run(["vault", "install", str(src), "--dest", str(dest)]) == 0 + assert _count_nodes(dest) == (3, 3) + assert not (dest / "README.md").exists() + + def test_install_reports_what_it_left_behind(tmp_path: Path, capsys) -> None: src = _make_vault(tmp_path / "src", count=2) (src / "README.md").write_text("# Vault\n", encoding="utf-8") From 28f17b5edf07cbcdb0972cd67c9c4af44f3717a1 Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 17:21:00 +0300 Subject: [PATCH 05/10] fix(scripts): audit what git will publish, not what sits on disk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit check_public_tree walked the filesystem and knew nothing about .gitignore, so any gitignored working directory failed it locally. A stray `packages/.orchestra/session-state.json` — a file git cannot publish under any circumstances — was enough to make the release preflight report a violation. CI never saw it, because CI checks out from git. That is the problem: a gate whose local runs are noisy and whose CI runs are clean teaches people to skip the local one, which is where it earns its keep. The audit now asks git what it would publish — tracked files plus untracked files that are not ignored — and scans that. Untracked-but-not-ignored files stay in scope deliberately: they are one `git add .` away from shipping. When git cannot answer (no repository, no git, an extracted tarball) it returns None and the walk runs as before, which is the conservative direction. Verified quieter without being weaker: gitignored .orchestra file present -> pass untracked, unignored `session-state.json` -> fail, named secret in an untracked, unignored file -> fail, named same secret inside a gitignored path -> pass, out of scope outside a git repository -> falls back to the full walk Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- scripts/check_public_tree.py | 58 +++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/scripts/check_public_tree.py b/scripts/check_public_tree.py index b5d27c1..00b914e 100755 --- a/scripts/check_public_tree.py +++ b/scripts/check_public_tree.py @@ -5,11 +5,48 @@ import argparse import re +import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] + +def publishable_paths() -> set[Path] | None: + """Every path git would publish: tracked, plus untracked-but-not-ignored. + + The audit is about what reaches the public repository, so asking git is + both more accurate and quieter than walking the filesystem. A gitignored + file cannot be published — flagging one is a false positive, and a gate + that cries wolf locally is one people learn to skip. Untracked files that + are *not* ignored stay in scope: they are one `git add .` from shipping. + + Returns None when git cannot answer — no repository, no git on PATH, an + extracted tarball — so the caller falls back to walking the tree, which is + the conservative direction. + """ + try: + result = subprocess.run( + [ + "git", + "-C", + str(ROOT), + "ls-files", + "--cached", + "--others", + "--exclude-standard", + "-z", + ], + capture_output=True, + check=True, + timeout=60, + ) + except (OSError, subprocess.SubprocessError): + return None + names = result.stdout.decode("utf-8", "replace").split("\0") + return {ROOT / name for name in names if name} + + FORBIDDEN_TOP_LEVEL = { ".agents", ".claude", @@ -107,7 +144,7 @@ } -def iter_public_text_files() -> list[Path]: +def iter_public_text_files(publishable: set[Path] | None) -> list[Path]: paths: list[Path] = [] for rel in TEXT_FILES_AT_ROOT: path = ROOT / rel @@ -121,6 +158,8 @@ def iter_public_text_files() -> list[Path]: for path in base.rglob("*"): if not path.is_file(): continue + if publishable is not None and path not in publishable: + continue if any(part in SKIP_DIRS for part in path.parts): continue if path.suffix.lower() in BINARY_SUFFIXES: @@ -152,13 +191,24 @@ def main() -> int: args = parser.parse_args() findings: list[str] = [] + publishable = publishable_paths() if not args.security_only: for name in sorted(FORBIDDEN_TOP_LEVEL): - if (ROOT / name).exists(): - findings.append(f"{name}: forbidden top-level public path") + candidate = ROOT / name + if not candidate.exists(): + continue + # A gitignored working directory (`.claude/`, `.orchestra/`) is not + # part of the public tree, so its presence on disk is not a finding. + if publishable is not None and not any( + path == candidate or candidate in path.parents for path in publishable + ): + continue + findings.append(f"{name}: forbidden top-level public path") for path in ROOT.rglob("*"): + if publishable is not None and path not in publishable: + continue if any(part in SKIP_DIRS for part in path.parts): continue if any( @@ -180,7 +230,7 @@ def main() -> int: if not args.security_only: patterns.update(HISTORY_PATTERNS) - for path in iter_public_text_files(): + for path in iter_public_text_files(publishable): findings.extend(scan_text(path, patterns)) if findings: From 34cc9a1c7e4398a672643e5f50c3ccb425ac61cc Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 17:22:55 +0300 Subject: [PATCH 06/10] fix(scripts): flag any private-account repository, not only SOSOVSKI/AKMS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The private-repository pattern matched `SOSOVSKI/AKMS` literally, so every other repository under that account passed the gate unnoticed. That is not hypothetical. compmech-reference-pack — the next package queued for publication — names `SOSOVSKI/MechDSL`, `SOSOVSKI/ConstKit` and `SOSOVSKI/SymbolicFemWorkbench` in its shipped `domain_pack/source_packs/*.yaml` and in `capabilities.py`. MechDSL is private and the other two are not publicly resolvable, so porting that package as-is would have disclosed three private repository names through a gate specifically built to prevent exactly that. The pattern now matches any repository under the account. The current tree still passes; a planted `SOSOVSKI/MechDSL` reference is now caught. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- scripts/check_public_tree.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/check_public_tree.py b/scripts/check_public_tree.py index 00b914e..2e22efd 100755 --- a/scripts/check_public_tree.py +++ b/scripts/check_public_tree.py @@ -87,7 +87,11 @@ def publishable_paths() -> set[Path] | None: ) HISTORY_PATTERNS = { - "private repository reference": re.compile(r"\bSOSOVSKI/AKMS\b", re.I), + # Any repository under the private account, not just SOSOVSKI/AKMS. The + # narrower pattern would have waved through `SOSOVSKI/MechDSL`, + # `SOSOVSKI/ConstKit` and `SOSOVSKI/SymbolicFemWorkbench`, which are named + # in compmech-reference-pack's shipped source packs and are not public. + "private repository reference": re.compile(r"\bSOSOVSKI/[\w.-]+", re.I), "plan or task identifier": re.compile( r"\b(?:ADM|AO|CAR)-\d+\b|" r"\bTask\s+P\d+(?:[-_]\d+)+\b|" From 2d26dddc8b77788a2ac15061460bed8ad52e2116 Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 17:45:36 +0300 Subject: [PATCH 07/10] feat: publish compmech-reference-pack as the fifth package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The computational-mechanics companion adapter, ported from the private workspace at 0.3.0 to join the lockstep release. It bridges akms-learn LSP excerpts to the MechDSL executable backend; the compile path stays an optional `mechdsl` extra so the backend is not pulled into a consumer's lock closure unless asked for. **Private references removed.** The package named three repositories that are not public — `SOSOVSKI/MechDSL` (private), `SOSOVSKI/ConstKit` and `SOSOVSKI/SymbolicFemWorkbench` (not resolvable at all) — in shipped source packs and in capabilities.py. MechDSL is repointed to `CEmM2/MechDSL`, the public repository that mechdsl-core, algo2code and ti-runtime all declare as their source on PyPI. The constkit and symbolic_fem_workbench source packs are dropped. Both were `capability_status: planned` — no adapter exists — and both named non-resolvable repositories, so shipping them would have advertised companions nobody can obtain while disclosing private repository names. The domain pack now declares only the mechdsl companion, and the test that asserted the two planned roles asserts that instead. Restore them when those repositories and their adapters are public. Logic-Loom references now name `CEmM2/Logic-Loom` explicitly rather than gesturing at an unqualified project. Internal plan identifiers (`P2-1` … `P2-6`) are stripped from every docstring and test. They mean nothing to a reader of the public package, and check_public_tree's pattern requires a `Task ` prefix, so the bare parenthesised form would have shipped unnoticed. **Wiring.** Workspace member and uv source, `PACKAGE_FILES` in check_versions, the pyright include list, a `compmech-reference-pack` build step and publish matrix leg in release.yml, and the `pypi-compmech-reference-pack` environment restricted to `v*` tags like the other four. The lock gains mechdsl-core, algo2code and their scientific dependencies (numpy, scipy, sympy, mpmath, opt-einsum, nrpylatex) from the all-extras resolution. No Taichi. Verified: 1752 tests pass, ruff format and check clean, pyright 0 errors with the new package in scope, strict docs build, public-tree audit passes, version audit passes, and all five packages' release globs claim exactly their own wheel and sdist with all ten distributions accounted for. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- .github/workflows/release.yml | 3 + docs/getting-started/akms/installation.md | 16 +- docs/index.md | 8 +- .../compmech_reference_pack/pyproject.toml | 48 +++ .../src/compmech_reference_pack/__init__.py | 22 ++ .../adapters/__init__.py | 15 + .../adapters/mechdsl_runner.py | 321 ++++++++++++++++++ .../compmech_reference_pack/capabilities.py | 67 ++++ .../domain_pack/domain_pack.yaml | 40 +++ .../domain_pack/source_packs/mechdsl.yaml | 26 ++ .../src/compmech_reference_pack/normalize.py | 192 +++++++++++ .../src/compmech_reference_pack/paths.py | 30 ++ .../tests/test_capabilities.py | 43 +++ .../tests/test_domain_pack.py | 57 ++++ .../tests/test_import.py | 63 ++++ .../tests/test_integration.py | 128 +++++++ .../tests/test_mechdsl_runner.py | 193 +++++++++++ .../tests/test_normalize.py | 121 +++++++ pyproject.toml | 4 +- scripts/check_versions.py | 3 + uv.lock | 139 ++++++++ 21 files changed, 1531 insertions(+), 8 deletions(-) create mode 100644 packages/compmech_reference_pack/pyproject.toml create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/__init__.py create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/adapters/__init__.py create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/adapters/mechdsl_runner.py create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/capabilities.py create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/domain_pack.yaml create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/mechdsl.yaml create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/normalize.py create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/paths.py create mode 100644 packages/compmech_reference_pack/tests/test_capabilities.py create mode 100644 packages/compmech_reference_pack/tests/test_domain_pack.py create mode 100644 packages/compmech_reference_pack/tests/test_import.py create mode 100644 packages/compmech_reference_pack/tests/test_integration.py create mode 100644 packages/compmech_reference_pack/tests/test_mechdsl_runner.py create mode 100644 packages/compmech_reference_pack/tests/test_normalize.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fc18c96..3240ddd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,6 +59,7 @@ jobs: uv build --package akms-learn --out-dir dist/packages uv build --package akms-nodes-gen --out-dir dist/packages uv build --package akms-failure-memory --out-dir dist/packages + uv build --package compmech-reference-pack --out-dir dist/packages uv run --with twine twine check dist/packages/* sha256sum dist/packages/* > dist/SHA256SUMS @@ -131,6 +132,8 @@ jobs: prefix: "akms_nodes_gen-" - package: akms-failure-memory prefix: "akms_failure_memory-" + - package: compmech-reference-pack + prefix: "compmech_reference_pack-" steps: - name: Download the verified distributions uses: actions/download-artifact@v8.0.1 diff --git a/docs/getting-started/akms/installation.md b/docs/getting-started/akms/installation.md index 324d8a2..e5dcbd7 100644 --- a/docs/getting-started/akms/installation.md +++ b/docs/getting-started/akms/installation.md @@ -23,9 +23,19 @@ That is the deterministic core: graph compilation, task-context resolution, loadouts and the CLI. The companion packages are independent installs: ```bash -pip install akms-learn # learning-packet compiler -pip install akms-nodes-gen # node generation and validation tooling -pip install akms-failure-memory # project-owned failure memory +pip install akms-learn # learning-packet compiler +pip install akms-nodes-gen # node generation and validation tooling +pip install akms-failure-memory # project-owned failure memory +pip install compmech-reference-pack # computational-mechanics companion adapter +``` + +`compmech-reference-pack` bridges computational-mechanics learning packets to +the [MechDSL](https://github.com/CEmM2/MechDSL) executable backend. The compile +and verify path is an extra, so the backend is not pulled in unless you ask +for it: + +```bash +pip install "compmech-reference-pack[mechdsl]" ``` The optional embedded coding-agent runtime is an extra rather than a separate diff --git a/docs/index.md b/docs/index.md index b8615c3..7000425 100644 --- a/docs/index.md +++ b/docs/index.md @@ -37,13 +37,13 @@ omnivorous agent framework: Batch Picker and generation tools for turning source collections into validated AKMS nodes, including a NotebookLM CLI path. -- :material-function-variant: __[Companion adapters](architecture/modules.md)__ +- :material-function-variant: __[compmech-reference-pack](architecture/modules.md)__ --- - Executable-domain bridges such as `compmech-reference-pack`, which maps - computational-mechanics LSP excerpts onto the MechDSL backend while - preserving provenance. + Companion adapter that maps computational-mechanics LSP excerpts onto the + MechDSL executable backend while preserving provenance. The compile path is + an optional extra. diff --git a/packages/compmech_reference_pack/pyproject.toml b/packages/compmech_reference_pack/pyproject.toml new file mode 100644 index 0000000..f29b024 --- /dev/null +++ b/packages/compmech_reference_pack/pyproject.toml @@ -0,0 +1,48 @@ +[project] +name = "compmech-reference-pack" +version = "0.3.0" +description = "Computational-mechanics companion adapter — bridges AKMS LSP excerpts to the MechDSL executable backend (Tier 2 of the AKMS executable-bridge)." +requires-python = ">=3.11,<3.14" +dependencies = [ + "akms-learn", +] + +[project.optional-dependencies] +# The executable-build path (MechDSLRunner.build_executable / transpile / +# verify) lazily imports the MechDSL Tier-1 backend — every mechdsl/algo2code +# import in src/ is function-scoped, so the package installs and imports +# cleanly without them. They are an optional extra so a downstream consumer +# (e.g. Logic-Loom's frozen core sidecar) can resolve and install +# compmech-reference-pack WITHOUT pulling mechdsl-core/algo2code — and +# transitively Taichi — into its uv lock closure. Install the `mechdsl` extra +# to enable the actual compile/transpile/verify capability. +mechdsl = [ + "mechdsl-core", + "algo2code", +] +dev = [ + "pytest>=9.0.2", + "compmech-reference-pack[mechdsl]", +] + +[build-system] +requires = ["setuptools>=68.0"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.setuptools.package-data] +compmech_reference_pack = [ + "domain_pack/*.yaml", + "domain_pack/source_packs/*.yaml", +] + +[tool.pytest.ini_options] +testpaths = ["tests"] +pythonpath = ["src"] +markers = [ + "unit: fast unit-level tests", + "integration: cross-module/integration tests", + "slow: tests that initialise Taichi (the only Taichi-paying adapter path)", +] diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/__init__.py b/packages/compmech_reference_pack/src/compmech_reference_pack/__init__.py new file mode 100644 index 0000000..feb5a6d --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/__init__.py @@ -0,0 +1,22 @@ +"""compmech_reference_pack — Tier-2 computational-mechanics companion adapter. + +Bridges AKMS ``akms_learn`` Learning Source Packet (LSP) excerpts to the +MechDSL Tier-1 ``mechdsl.integration`` façade: it normalises human-authored +algpseudocode into algo2code-grammar-clean form, then emits executable Python +and/or compiled-solver summaries with provenance. + +This package depends on **both** ``akms-learn`` and ``mechdsl-core`` (plus +``algo2code``, MechDSL's transpiler backend). It registers the +``executable_bridge`` adapter so ``akms_learn`` reports +``executable_bridge_adapter = available``. + +Companion-adapter pattern: MechDSL stays AKMS-unaware; this package is the only +place that knows about both sides. The public surface is populated across the +the executable-bridge tier. +""" + +from __future__ import annotations + +__version__ = "0.1.0" + +__all__: list[str] = [] diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/adapters/__init__.py b/packages/compmech_reference_pack/src/compmech_reference_pack/adapters/__init__.py new file mode 100644 index 0000000..8ac74bb --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/adapters/__init__.py @@ -0,0 +1,15 @@ +"""compmech_reference_pack adapters — the executable-bridge runner (Tier 2).""" + +from __future__ import annotations + +from compmech_reference_pack.adapters.mechdsl_runner import ( + MechDSLRunner, + adapter_registry_overrides, + available_adapter_registry, +) + +__all__ = [ + "MechDSLRunner", + "adapter_registry_overrides", + "available_adapter_registry", +] diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/adapters/mechdsl_runner.py b/packages/compmech_reference_pack/src/compmech_reference_pack/adapters/mechdsl_runner.py new file mode 100644 index 0000000..03e7740 --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/adapters/mechdsl_runner.py @@ -0,0 +1,321 @@ +"""mechdsl_runner.py — MechDSLRunner, the executable_bridge adapter. + +Bridges a bounded AKMS LSP excerpt to the MechDSL Tier-1 façade +(``mechdsl.integration``) and assembles a provenance-carrying artefact dict. + +Contract (the real one, NOT the spec's ``build_artifacts``):: + + build_executable(excerpt: dict, *, options: dict | None = None) -> dict + +Behaviour +--------- +- **Emit-only by default.** ``build_executable`` normalises the node's + ``extracted["implementation"]`` (algpseudocode) and calls Tier-1 + ``transpile_algorithm``, and — when a ``% mechanics`` problem source plus an + energy ``derivation`` are present — Tier-1 ``compile_from_sources``. Both are + Taichi-free. +- **Taichi only on demand.** Tier-1 ``verify`` is called **only** when + ``options["run_verify"]`` is truthy; that is the single Taichi-paying branch. +- **Never invalidates the packet** (spec 09 §7 rule 5): a transpile/compile + failure is captured into ``warnings`` and reported as ``status="error"`` + only when the caller explicitly required executable output + (``options["require_executable"]``); otherwise ``status`` stays ``"ok"``. + +No-mutation invariant: this adapter never writes to any AKMS path. +""" + +from __future__ import annotations + +import re +from typing import Any + +from akms_learn.adapters.status import AdapterStatus, adapter_registry + +ADAPTER_ID = "compmech.mechdsl_runner" + +__all__ = [ + "ADAPTER_ID", + "MechDSLRunner", + "adapter_registry_overrides", + "available_adapter_registry", +] + + +def adapter_registry_overrides() -> dict[str, AdapterStatus]: + """Registry override that marks the executable bridge available.""" + return {"executable_bridge_adapter": AdapterStatus.available} + + +def available_adapter_registry() -> dict[str, AdapterStatus]: + """Return the akms_learn adapter registry with this adapter marked available.""" + return adapter_registry(adapter_registry_overrides()) + + +def _algo_name_from_node_id(node_id: str) -> str: + """Derive a safe algo2code algorithm name from a node id.""" + tail = node_id.rsplit(".", 1)[-1].rsplit("/", 1)[-1] + cleaned = re.sub(r"[^0-9A-Za-z_]", "_", tail).strip("_") + return cleaned or "algorithm" + + +class MechDSLRunner: + """ExecutableBridgeAdapter implementation backed by MechDSL Tier-1. + + Satisfies ``akms_learn.adapters.protocols.ExecutableBridgeAdapter`` via + structural subtyping (the protocol is ``@runtime_checkable``). + """ + + adapter_id = ADAPTER_ID + + # -- protocol surface --------------------------------------------------- + + def build_executable( + self, excerpt: dict[str, Any], *, options: dict[str, Any] | None = None + ) -> dict[str, Any]: + """Build an executable artefact from a bounded LSP excerpt. + + Returns the 8-key contract dict ``{adapter, status, emitted_source, + transpiled, normalized_input, provenance, vv_plan, warnings}``. When + ``options["run_verify"]`` is truthy a 9th key ``verification`` (the + Tier-1 ``verify`` result) is added — that opt-in path is the only one + that pays the Taichi cost. Never raises on a malformed excerpt. + """ + options = options or {} + run_verify = bool(options.get("run_verify", False)) + require_executable = bool(options.get("require_executable", False)) + + node = self._select_node(excerpt) + node_id = str(node.get("node_id") or excerpt.get("node_id") or "") + extracted = node.get("extracted") + if not isinstance(extracted, dict): + extracted = {} + implementation = extracted.get("implementation") + derivation = extracted.get("derivation") + problem = extracted.get("problem") + + warnings: list[str] = [] + status = "ok" + normalized_input: str | None = None + transpiled: dict[str, Any] | None = None + emitted_source: str | None = None + + # --- implementation -> normalize -> Tier-1 transpile (Taichi-free) --- + if implementation: + from compmech_reference_pack.normalize import normalize + + norm = normalize( + implementation, algorithm_name=_algo_name_from_node_id(node_id) + ) + normalized_input = norm.normalized + warnings.extend(norm.warnings) + if norm.algorithmic_block_found: + try: + from mechdsl.integration import transpile_algorithm + except ImportError as exc: + warnings.append( + "MechDSL backend unavailable; install " + '"compmech-reference-pack[mechdsl]" ' + f"({type(exc).__name__}: {exc})" + ) + if require_executable: + status = "error" + else: + try: + transpiled = transpile_algorithm( + norm.normalized, backend="taichi" + ) + if not transpiled.get("valid_python", False): + warnings.append( + "transpiled code did not compile as valid Python" + ) + if require_executable: + status = "error" + except Exception as exc: + warnings.append( + f"transpile failed: {type(exc).__name__}: {exc}" + ) + if require_executable: + status = "error" + + # --- derivation (+ problem) -> Tier-1 compile (Taichi-free) ---------- + if derivation and problem: + try: + from mechdsl.integration import compile_from_sources + except ImportError as exc: + warnings.append( + "MechDSL backend unavailable; install " + '"compmech-reference-pack[mechdsl]" ' + f"({type(exc).__name__}: {exc})" + ) + if require_executable: + status = "error" + else: + try: + compiled = compile_from_sources( + problem_source=problem, energy_source=derivation + ) + emitted_source = compiled["emitted_source"] + except Exception as exc: + warnings.append( + f"compile_from_sources failed: {type(exc).__name__}: {exc}" + ) + if require_executable: + status = "error" + elif derivation and not problem: + warnings.append( + "node carries a derivation but no '% mechanics' problem source; " + "skipping compile_from_sources (provide extracted['problem'] to compile)" + ) + + if implementation is None and derivation is None: + status = "error" + warnings.append( + f"excerpt node {node_id!r} carries neither an implementation nor a " + "derivation; nothing to build" + ) + + result: dict[str, Any] = { + "adapter": ADAPTER_ID, + "status": status, + "emitted_source": emitted_source, + "transpiled": transpiled, + "normalized_input": normalized_input, + "provenance": { + node_id: { + "sections": self._sections(node), + "references": self._references(node_id, node, excerpt), + } + }, + "vv_plan": self._vv_plan(node_id, node, excerpt, options), + "warnings": warnings, + } + + # --- the only Taichi-paying branch ---------------------------------- + if run_verify: + result["verification"] = self._run_verify(options, warnings) + + return result + + # -- extra surface (per plan: status() / can_handle()) ------------------ + + def status(self) -> dict[str, Any]: + """Lightweight, Taichi-free availability descriptor for status routes.""" + return { + "adapter": ADAPTER_ID, + "available": True, + "companion_role": "executable_bridge", + "taichi_required_for": ["verify"], + } + + def can_handle(self, excerpt: dict[str, Any]) -> bool: + """True when the excerpt has a node carrying implementation/derivation. + + Total: returns ``False`` (never raises) for any malformed excerpt + shape — missing ``nodes``, non-dict nodes, non-dict ``extracted``. + """ + node = self._select_node(excerpt) + extracted = node.get("extracted") + if not isinstance(extracted, dict): + return False + return bool(extracted.get("implementation") or extracted.get("derivation")) + + # -- internals ---------------------------------------------------------- + + @staticmethod + def _select_node(excerpt: dict[str, Any]) -> dict[str, Any]: + """Pick the node dict to build from. + + Accepts a node-shaped excerpt directly, a ``{"nodes": [...]}`` excerpt + (first node carrying implementation/derivation, else the first node), + or any dict (treated as the node). + """ + nodes = excerpt.get("nodes") + if isinstance(nodes, list): + dict_nodes = [n for n in nodes if isinstance(n, dict)] + for node in dict_nodes: + extracted = node.get("extracted") + if isinstance(extracted, dict) and ( + extracted.get("implementation") or extracted.get("derivation") + ): + return node + # No build-bearing node — return the first dict node, or {} so + # callers never touch a non-dict (None, str, …). + return dict_nodes[0] if dict_nodes else {} + return excerpt + + @staticmethod + def _sections(node: dict[str, Any]) -> Any: + return node.get("included_sections") or node.get("sections") or [] + + @staticmethod + def _references( + node_id: str, node: dict[str, Any], excerpt: dict[str, Any] + ) -> list[Any]: + """Collect references attributable to this node. + + Prefers node-local references; otherwise filters packet-level + references by ``source_node_ids`` membership (falling back to all). + """ + node_refs = node.get("references") + if isinstance(node_refs, list) and node_refs: + return list(node_refs) + + packet_refs = excerpt.get("references") + if not isinstance(packet_refs, list): + return [] + scoped = [ + ref + for ref in packet_refs + if isinstance(ref, dict) and node_id in (ref.get("source_node_ids") or []) + ] + return scoped or list(packet_refs) + + @classmethod + def _vv_plan( + cls, + node_id: str, + node: dict[str, Any], + excerpt: dict[str, Any], + options: dict[str, Any], + ) -> dict[str, Any]: + """Assemble a verification-and-validation plan {benchmark, citation}. + + The citation is drawn from the same node-scoped reference list used for + provenance (via :meth:`_references`), so the two never disagree. + """ + extracted = node.get("extracted") + if not isinstance(extracted, dict): + extracted = {} + benchmark = ( + options.get("benchmark") + or extracted.get("benchmark") + or excerpt.get("benchmark") + ) + citation: Any = None + for ref in cls._references(node_id, node, excerpt): + if isinstance(ref, dict): + citation = ref.get("citation") or ref.get("title") + if citation: + break + return {"benchmark": benchmark, "citation": citation} + + @staticmethod + def _run_verify(options: dict[str, Any], warnings: list[str]) -> dict[str, Any]: + """Run the single Taichi-paying Tier-1 verify branch.""" + kind = options.get("verify_kind", "patch_test") + params = options.get("verify_params", {}) + + try: + from mechdsl.integration import verify + + return verify(kind, params) + except ImportError as exc: + warnings.append( + "MechDSL backend unavailable; install " + '"compmech-reference-pack[mechdsl]" ' + f"({type(exc).__name__}: {exc})" + ) + return {"kind": kind, "passed": False, "details": {"error": str(exc)}} + except Exception as exc: + warnings.append(f"verify failed: {type(exc).__name__}: {exc}") + return {"kind": kind, "passed": False, "details": {"error": str(exc)}} diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/capabilities.py b/packages/compmech_reference_pack/src/compmech_reference_pack/capabilities.py new file mode 100644 index 0000000..b4e4dc1 --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/capabilities.py @@ -0,0 +1,67 @@ +"""Capability declarations for compmech_reference_pack. + +`CEmM2/Logic-Loom `_ imports this package +from its ``GET /api/mechdsl/status`` route and reads the capability surface to +decide whether to expose the MechDSL gate. +This module is deliberately import-light and **Taichi-free**: it declares +*what* the package offers; it never runs a solve or initialises Taichi. + +Two capabilities are declared: + +- ``executable_bridge_adapter`` — the package registers ``MechDSLRunner`` as + the ``executable_bridge`` adapter (``akms_learn`` reports it available). +- ``code_mirror_provenance`` — ``build_executable`` attaches per-node + provenance (source sections + references) to every emitted artefact. +""" + +from __future__ import annotations + +from compmech_reference_pack import __version__ + +__all__ = [ + "ADAPTER_ID", + "CODE_MIRROR_PROVENANCE", + "EXECUTABLE_BRIDGE_ADAPTER", + "capabilities", +] + +#: Stable id of the executable-bridge adapter this package registers. +ADAPTER_ID = "compmech.mechdsl_runner" + +#: Capability keys (also the akms_learn adapter-registry capability names). +EXECUTABLE_BRIDGE_ADAPTER = "executable_bridge_adapter" +CODE_MIRROR_PROVENANCE = "code_mirror_provenance" + + +def capabilities() -> dict: + """Return the machine-readable capability surface for status discovery. + + Shape consumed by Logic-Loom's status route:: + + {package, version, domain_pack, adapter_id, capabilities: {...}} + + The dict is JSON-serialisable and contains no runtime objects. + """ + return { + "package": "compmech_reference_pack", + "version": __version__, + "domain_pack": "compmech.reference", + "adapter_id": ADAPTER_ID, + "capabilities": { + EXECUTABLE_BRIDGE_ADAPTER: { + "available": True, + "adapter_id": ADAPTER_ID, + "companion_role": "executable_bridge", + "actions": ["emit", "transpile", "verify"], + # Mirrors the Tier-1 contract: only ``verify`` pays Taichi. + "taichi_required_for": ["verify"], + }, + CODE_MIRROR_PROVENANCE: { + "available": True, + "source_pack_id": "compmech.mechdsl", + "repo": "CEmM2/MechDSL", + # build_executable attaches {node_id: {sections, references}}. + "provenance_keys": ["sections", "references"], + }, + }, + } diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/domain_pack.yaml b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/domain_pack.yaml new file mode 100644 index 0000000..d9fe561 --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/domain_pack.yaml @@ -0,0 +1,40 @@ +domain_pack_schema: akms-learn-domain-pack/v1 +domain_id: compmech +pack_id: compmech.reference +name: Computational Mechanics Reference Pack +version: "0.1.0" +status: reference +summary: >- + Reference computational-mechanics domain pack for AKMS Learn. Promoted from + the AKMS_learn test fixture by compmech_reference_pack (Tier-2 executable + bridge); the MechDSL companion is now an available executable runner. +compatibility: + akms_learn_schema_min: learn/v0.1 + akms_learn_schema_max: learn/v0.1 +roots: + nodes: nodes/compmech + code_mirror: code-mirror/compmech + examples: learning_examples/compmech + bundles: lesson_bundles/compmech +capabilities: + static_markdown: true + static_notebook: true + executable_notebook: false + external_runner: true + code_mirror: true +# The `constkit` and `symbolic_fem_workbench` companions were dropped from the +# public pack. Both were `planned` — no adapter exists — and both named source +# repositories that are not publicly resolvable, so shipping them would have +# advertised capabilities nobody can use while disclosing private repository +# names. Restore them when those repositories and their adapters are public. +companion_roles: + - id: mechdsl + package_name: compmech.mechdsl + runtime_hint: required + capability_status: available +source_packs: + - source_packs/mechdsl.yaml +provenance: + source_repos: [] + generated_vault_ref: null + zotero_collection_refs: [] diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/mechdsl.yaml b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/mechdsl.yaml new file mode 100644 index 0000000..45e22d6 --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/mechdsl.yaml @@ -0,0 +1,26 @@ +source_pack_schema: akms-learn-source-pack/v1 +source_pack_id: compmech.mechdsl +name: MechDSL Executable Bridge +version: "0.1.0" +companion_role: executable_bridge +capability_status: available +repo: + kind: github + name: CEmM2/MechDSL + ref: main +roots: + docs: dev/design_docs + code: packages/mechdsl-core/src/mechdsl + examples: dev/examples + tests: packages/mechdsl-core/tests +capabilities: + static_code_mirror: true + static_lessons: true + notebook_cells: false + executable_runner: true +runtime: + required_python: ">=3.12,<3.13" + dependencies: [] +adapter: + adapter_id: compmech.mechdsl_runner + status: available diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/normalize.py b/packages/compmech_reference_pack/src/compmech_reference_pack/normalize.py new file mode 100644 index 0000000..8b45589 --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/normalize.py @@ -0,0 +1,192 @@ +"""normalize.py — rewrite human-authored algpseudocode into algo2code-clean form. + +The Tier-2 adapter's pre-processing core. An LSP node's +``extracted["implementation"]`` is human/markdown-authored algpseudocode; +``algo2code.transpile`` expects an ``algorithmic`` block optionally preceded by +``% algorithm/backend/args/type`` directive lines. + +What this pass actually does +---------------------------- +Empirically, MechDSL's current ``algo2code`` expression grammar already +subsumes the rewrites the original plan anticipated (``\\sqrt{3/2}``, +``\\frac{a}{b}``, ``\\cdot``, ``\\left/\\right``, Greek letters, ``^{...}``, +and ``\\If/\\Else/\\ElsIf/\\While/\\For`` control flow all transpile as-is). +So the genuinely-useful work here is: + +1. **Extract** the ``\\begin{algorithmic} … \\end{algorithmic}`` block out of + surrounding markdown (prose, code fences) so the source is bounded and the + *absence* of an algorithm is detectable (``algo2code`` silently emits an + empty function otherwise). +2. **Synthesise directives** — prepend ``% algorithm `` / ``% backend + taichi`` when the author didn't, so the emitted function is meaningfully + named instead of the ``algo2code`` default ``algorithm``; author-supplied + directives are preserved. +3. **Surface parser failures as structured warnings, never raise** — per spec + 09 §7 rule 5 (a failed adapter must not invalidate the packet unless + executable output was explicitly required). + +The public deliverable is :func:`normalize_algpseudocode` (``str -> str``); +:func:`normalize` wraps it with a trial parse and the warning report the +adapter consumes. +""" + +from __future__ import annotations + +import re +from dataclasses import dataclass + +__all__ = [ + "NormalizationResult", + "extract_algorithmic_block", + "normalize", + "normalize_algpseudocode", +] + +_ALGORITHMIC_RE = re.compile( + r"\\begin\{algorithmic\}(?:\[[^\]]*\])?(?P.*?)\\end\{algorithmic\}", + re.DOTALL, +) +_FENCE_RE = re.compile(r"^[ \t]*```[^\n]*$", re.MULTILINE) +# ":=" is the only assignment arrow algo2code does not accept; "\gets" and +# "\leftarrow" parse natively but we canonicalise all three to "=". +_ARROW_RE = re.compile(r":=|\\gets|\\leftarrow") +_DIRECTIVE_KEYWORDS = frozenset({"algorithm", "backend", "args", "type"}) + + +@dataclass(frozen=True) +class NormalizationResult: + """Outcome of normalising one implementation excerpt. + + Attributes + ---------- + normalized: + algo2code-ready source (synthesised directives + algorithmic block). + algorithmic_block_found: + Whether an ``\\begin{algorithmic}`` block was present in the input. + parses: + Whether ``algo2code.parse_algorithm`` accepted the normalised source. + warnings: + Structured, human-readable warnings (missing block, parse errors). + Never empty when ``parses`` is ``False`` or the block was absent. + """ + + normalized: str + algorithmic_block_found: bool + parses: bool + warnings: tuple[str, ...] = () + + +def extract_algorithmic_block(impl_md: str) -> str | None: + """Return the inner body of the first ``algorithmic`` block, or ``None``. + + Markdown code fences are stripped first so a fenced ``\\begin{algorithmic}`` + is still found. The returned body excludes the ``\\begin``/``\\end`` markers. + """ + if not impl_md: + return None + text = _FENCE_RE.sub("", impl_md) + match = _ALGORITHMIC_RE.search(text) + if match is None: + return None + return match.group("body").strip("\n") + + +def _sanitize_identifier(name: str) -> str: + """Coerce an arbitrary string into a safe algo2code algorithm identifier.""" + cleaned = re.sub(r"[^0-9A-Za-z_]", "_", name).strip("_") + if not cleaned: + return "algorithm" + if cleaned[0].isdigit(): + cleaned = f"a_{cleaned}" + return cleaned + + +def _collect_directives(impl_md: str) -> list[str]: + """Collect author-supplied ``% algorithm/backend/args/type`` directives. + + Only lines *before* the algorithmic block are considered, so ``%`` lines + that happen to live inside the block are not mistaken for directives. + """ + head = impl_md + begin = impl_md.find(r"\begin{algorithmic}") + if begin != -1: + head = impl_md[:begin] + directives: list[str] = [] + for raw in head.splitlines(): + stripped = raw.strip() + if not stripped.startswith("%"): + continue + content = stripped[1:].strip() + first = content.split(None, 1)[0] if content else "" + if first in _DIRECTIVE_KEYWORDS: + directives.append(content) + return directives + + +def normalize_algpseudocode(impl_md: str, *, algorithm_name: str | None = None) -> str: + """Rewrite a human-authored implementation excerpt into algo2code source. + + Extracts the ``algorithmic`` block, canonicalises assignment arrows, and + prepends synthesised ``% algorithm``/``% backend`` directives (preserving + any the author already supplied). Never raises: a missing block yields an + empty algorithmic shell, which :func:`normalize` flags as a warning. + """ + body = extract_algorithmic_block(impl_md) + if body is None: + body = "" + body = _ARROW_RE.sub("=", body) + + existing = _collect_directives(impl_md) + # Match both "algorithm " and a bare "algorithm" directive so a + # name-less author directive doesn't get a synthesised one appended too. + has_name = any(d == "algorithm" or d.startswith("algorithm ") for d in existing) + has_backend = any(d == "backend" or d.startswith("backend ") for d in existing) + + lines: list[str] = [] + if not has_name: + lines.append( + f"% algorithm {_sanitize_identifier(algorithm_name or 'algorithm')}" + ) + if not has_backend: + lines.append("% backend taichi") + lines.extend(f"% {d}" for d in existing) + lines.append(r"\begin{algorithmic}") + if body: + lines.append(body) + lines.append(r"\end{algorithmic}") + return "\n".join(lines) + + +def normalize( + impl_md: str, *, algorithm_name: str | None = None +) -> NormalizationResult: + """Normalise an excerpt and report parse status + structured warnings. + + Wraps :func:`normalize_algpseudocode` with a trial ``algo2code`` parse so + the adapter can attach warnings without ever crashing the packet. + """ + found = extract_algorithmic_block(impl_md) is not None + normalized = normalize_algpseudocode(impl_md, algorithm_name=algorithm_name) + + warnings: list[str] = [] + if not found: + warnings.append( + r"no \begin{algorithmic} block found in implementation excerpt; " + "emitted source will be an empty function" + ) + + parses = False + try: + from algo2code import parse_algorithm + + parse_algorithm(normalized) + parses = True + except Exception as exc: + warnings.append(f"algo2code parse failed: {type(exc).__name__}: {exc}") + + return NormalizationResult( + normalized=normalized, + algorithmic_block_found=found, + parses=parses, + warnings=tuple(warnings), + ) diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/paths.py b/packages/compmech_reference_pack/src/compmech_reference_pack/paths.py new file mode 100644 index 0000000..7f9ca5e --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/paths.py @@ -0,0 +1,30 @@ +"""Filesystem accessors for the promoted compmech domain pack. + +The domain pack and its source packs ship as package data under +``compmech_reference_pack/domain_pack/``. These helpers return concrete +``Path`` objects so the ``akms_learn`` descriptor loaders — and the +`CEmM2/Logic-Loom `_ status route — can +read them without hardcoding the install layout. +""" + +from __future__ import annotations + +from importlib import resources +from pathlib import Path + +__all__ = ["domain_pack_dir", "domain_pack_path", "source_pack_path"] + + +def domain_pack_dir() -> Path: + """Absolute path to the packaged ``domain_pack/`` data directory.""" + return Path(str(resources.files("compmech_reference_pack") / "domain_pack")) + + +def domain_pack_path() -> Path: + """Absolute path to the promoted ``domain_pack.yaml``.""" + return domain_pack_dir() / "domain_pack.yaml" + + +def source_pack_path(name: str) -> Path: + """Absolute path to a source-pack yaml by stem (e.g. ``"mechdsl"``).""" + return domain_pack_dir() / "source_packs" / f"{name}.yaml" diff --git a/packages/compmech_reference_pack/tests/test_capabilities.py b/packages/compmech_reference_pack/tests/test_capabilities.py new file mode 100644 index 0000000..014fdab --- /dev/null +++ b/packages/compmech_reference_pack/tests/test_capabilities.py @@ -0,0 +1,43 @@ +"""capability surface is declared and readable by a status route.""" + +from __future__ import annotations + +import json + +import pytest +from compmech_reference_pack.capabilities import ( + CODE_MIRROR_PROVENANCE, + EXECUTABLE_BRIDGE_ADAPTER, + capabilities, +) + + +@pytest.mark.unit +def test_declares_both_capabilities() -> None: + caps = capabilities()["capabilities"] + assert caps[EXECUTABLE_BRIDGE_ADAPTER]["available"] is True + assert caps[CODE_MIRROR_PROVENANCE]["available"] is True + + +@pytest.mark.unit +def test_adapter_id_consistent() -> None: + surface = capabilities() + assert surface["adapter_id"] == "compmech.mechdsl_runner" + assert ( + surface["capabilities"][EXECUTABLE_BRIDGE_ADAPTER]["adapter_id"] + == "compmech.mechdsl_runner" + ) + + +@pytest.mark.unit +def test_taichi_required_for_mirrors_tier1() -> None: + bridge = capabilities()["capabilities"][EXECUTABLE_BRIDGE_ADAPTER] + assert bridge["taichi_required_for"] == ["verify"] + + +@pytest.mark.unit +def test_surface_is_json_serialisable() -> None: + """Logic-Loom serialises the surface into its status response.""" + recovered = json.loads(json.dumps(capabilities())) + assert recovered["package"] == "compmech_reference_pack" + assert recovered["domain_pack"] == "compmech.reference" diff --git a/packages/compmech_reference_pack/tests/test_domain_pack.py b/packages/compmech_reference_pack/tests/test_domain_pack.py new file mode 100644 index 0000000..7fbdfb9 --- /dev/null +++ b/packages/compmech_reference_pack/tests/test_domain_pack.py @@ -0,0 +1,57 @@ +"""The promoted domain pack reads back through the akms_learn loaders. + +Acceptance: the akms_learn descriptor loader reports ``compmech.mechdsl`` +available (both the domain-pack companion role and the source-pack / +adapter status), while the still-planned companions stay planned. +""" + +from __future__ import annotations + +import pytest +from akms_learn.domain_packs.capabilities import CapabilityStatus +from akms_learn.domain_packs.registry import ( + load_descriptor_from_yaml, + load_source_pack_from_yaml, +) +from compmech_reference_pack.paths import domain_pack_path, source_pack_path + + +@pytest.mark.unit +def test_domain_pack_descriptor_parses() -> None: + desc = load_descriptor_from_yaml(domain_pack_path()) + assert desc.id == "compmech.reference" + + +@pytest.mark.unit +def test_mechdsl_companion_role_is_available() -> None: + desc = load_descriptor_from_yaml(domain_pack_path()) + roles = {r.id: r for r in desc.companion_roles} + assert roles["mechdsl"].capability_status is CapabilityStatus.available + + +@pytest.mark.unit +def test_mechdsl_source_pack_and_adapter_available() -> None: + sp = load_source_pack_from_yaml(source_pack_path("mechdsl")) + assert sp.id == "compmech.mechdsl" + assert sp.companion_role == "executable_bridge" + assert sp.capability_status is CapabilityStatus.available + assert sp.adapter is not None + assert sp.adapter["status"] == "available" + + +@pytest.mark.unit +def test_public_pack_declares_only_shippable_companions() -> None: + """Every companion role in the public pack is one a user can actually use. + + The `constkit` and `symbolic_fem_workbench` roles were dropped on + publication: both were `planned` — no adapter exists — and both named + source repositories that are not publicly resolvable. A pack that + advertises companions nobody can obtain is worse than one that stays quiet + about them, so the public descriptor declares only what ships. + """ + desc = load_descriptor_from_yaml(domain_pack_path()) + roles = {r.id: r for r in desc.companion_roles} + assert set(roles) == {"mechdsl"} + assert all( + r.capability_status is CapabilityStatus.available for r in desc.companion_roles + ) diff --git a/packages/compmech_reference_pack/tests/test_import.py b/packages/compmech_reference_pack/tests/test_import.py new file mode 100644 index 0000000..4feadaa --- /dev/null +++ b/packages/compmech_reference_pack/tests/test_import.py @@ -0,0 +1,63 @@ +"""The compmech_reference_pack package exists and its dependencies resolve. + +Acceptance criteria: + - ``uv sync`` resolves akms-learn into the package env (the hard dependency). + - the package is importable without the MechDSL backend installed. + - with the ``mechdsl`` extra installed, the Tier-1 backend (mechdsl-core) and + algo2code resolve and import Taichi-free. + +akms-learn (the Tier-2 host) is a hard dependency and must always import. +mechdsl-core (the Tier-1 backend) and algo2code (its transpiler) are an optional +``[mechdsl]`` extra — their import tests ``importorskip`` so a core-only install +(e.g. a downstream consumer that omits the extra to keep Taichi out of its lock +closure) collects green, while a full install still validates resolution. +""" + +from __future__ import annotations + +import importlib +import sys + +import pytest + + +@pytest.mark.unit +def test_import_package() -> None: + """The package imports cleanly and exposes a version.""" + mod = importlib.import_module("compmech_reference_pack") + assert mod.__version__ + + +@pytest.mark.unit +def test_akms_learn_dependency_resolves() -> None: + """akms-learn (Tier-2 host) — the adapter protocols module — is importable.""" + protocols = importlib.import_module("akms_learn.adapters.protocols") + assert hasattr(protocols, "ExecutableBridgeAdapter") + + +@pytest.mark.unit +def test_mechdsl_tier1_dependency_resolves_taichi_free() -> None: + """With the ``mechdsl`` extra, the Tier-1 façade imports Taichi-free. + + Skips when the optional backend is not installed (a core-only consumer that + omits ``compmech-reference-pack[mechdsl]``). + """ + pytest.importorskip( + "mechdsl.integration", + reason="optional 'mechdsl' extra not installed (install compmech-reference-pack[mechdsl])", + ) + assert "taichi" not in sys.modules, ( + "importing mechdsl.integration must not initialise Taichi" + ) + + +@pytest.mark.unit +def test_algo2code_dependency_resolves() -> None: + """With the ``mechdsl`` extra, algo2code (the transpiler backend) is importable. + + Skips when the optional backend is not installed. + """ + pytest.importorskip( + "algo2code", + reason="optional 'mechdsl' extra not installed (install compmech-reference-pack[mechdsl])", + ) diff --git a/packages/compmech_reference_pack/tests/test_integration.py b/packages/compmech_reference_pack/tests/test_integration.py new file mode 100644 index 0000000..59ac1fc --- /dev/null +++ b/packages/compmech_reference_pack/tests/test_integration.py @@ -0,0 +1,128 @@ +"""end-to-end executable-bridge integration on a fixture LSP excerpt. + +Covers the deliverable acceptance: + - isinstance(MechDSLRunner(), ExecutableBridgeAdapter); + - a radial-return node excerpt -> build_executable -> valid transpiled Python + + provenance carrying references (Simo & Hughes); + - run_verify=False does not initialise Taichi (fresh-interpreter subprocess); + - one run_verify=True slow test that exercises the Taichi-paying branch. +""" + +from __future__ import annotations + +import subprocess +import sys + +import pytest +from akms_learn.adapters.protocols import ExecutableBridgeAdapter +from compmech_reference_pack.adapters.mechdsl_runner import MechDSLRunner + +# A radial-return learning node, markdown-authored (no % directives) — the +# common LSP-node shape, with a Simo & Hughes provenance reference. +_RADIAL_RETURN_IMPL = "\n".join( + [ + "## Return mapping (J2, isotropic power-law hardening)", + "", + "```latex", + r"\begin{algorithmic}", + r"\State $sy \gets sigy0 + K \cdot \alpha^{n}$", + r"\State $f = sigma_eq - sy$", + r"\If{$f < 0$}", + r"\State $dl = 0$", + r"\Else", + r"\State $dl = f / (3 \cdot mu)$", + r"\EndIf", + r"\end{algorithmic}", + "```", + ] +) + + +def _radial_return_excerpt() -> dict: + return { + "node_id": "compmech.node.radial_return_j2", + "extracted": {"implementation": _RADIAL_RETURN_IMPL}, + "included_sections": [ + {"heading": "Return-mapping algorithm", "source_path": "dev/notes/j2.md"} + ], + "references": [ + { + "citation": "Simo & Hughes (1998), Computational Inelasticity", + "source_node_ids": ["compmech.node.radial_return_j2"], + } + ], + } + + +@pytest.mark.integration +def test_runner_satisfies_protocol() -> None: + assert isinstance(MechDSLRunner(), ExecutableBridgeAdapter) + + +@pytest.mark.integration +def test_build_executable_end_to_end() -> None: + result = MechDSLRunner().build_executable(_radial_return_excerpt()) + + assert result["adapter"] == "compmech.mechdsl_runner" + assert result["status"] == "ok" + + transpiled = result["transpiled"] + assert transpiled is not None + assert transpiled["valid_python"] is True + assert transpiled["entry_point"] == "radial_return_j2" + + assert result["normalized_input"] + prov = result["provenance"]["compmech.node.radial_return_j2"] + assert any("Simo & Hughes" in str(ref) for ref in prov["references"]) + assert prov["sections"] + + # Emit-only default: no Taichi-paying verification attached. + assert "verification" not in result + + +@pytest.mark.integration +def test_run_verify_false_does_not_initialise_taichi() -> None: + """The load-bearing contract: the default emit path stays Taichi-free. + + Run in a fresh interpreter so no parent-process Taichi import contaminates + the check. + """ + script = "\n".join( + [ + "import sys", + "from compmech_reference_pack.adapters.mechdsl_runner import MechDSLRunner", + "impl = chr(10).join([r'\\begin{algorithmic}', r'\\State $y = a \\cdot b$', r'\\end{algorithmic}'])", + "excerpt = {'node_id': 'n', 'extracted': {'implementation': impl}}", + "res = MechDSLRunner().build_executable(excerpt, options={'run_verify': False})", + "assert res['transpiled'] is not None and res['transpiled']['valid_python']", + "loaded = 'taichi' in sys.modules", + "print('taichi_loaded:', loaded)", + "sys.exit(1 if loaded else 0)", + ] + ) + proc = subprocess.run( + [sys.executable, "-c", script], capture_output=True, text=True, timeout=120 + ) + assert proc.returncode == 0, ( + "build_executable(run_verify=False) initialised Taichi.\n" + f"stdout: {proc.stdout!r}\nstderr: {proc.stderr!r}" + ) + assert "taichi_loaded: False" in proc.stdout + + +@pytest.mark.integration +@pytest.mark.slow +def test_run_verify_true_pays_taichi_and_returns_result() -> None: + """run_verify=True reaches the Tier-1 verify branch (the Taichi-paying path).""" + options = { + "run_verify": True, + "verify_kind": "patch_test", + "verify_params": {"nx": 1, "ny": 1, "nz": 1, "lam": 1.0, "mu": 1.0}, + } + result = MechDSLRunner().build_executable(_radial_return_excerpt(), options=options) + + assert "verification" in result + verification = result["verification"] + assert verification["kind"] == "patch_test" + assert isinstance(verification["passed"], bool) + assert "details" in verification diff --git a/packages/compmech_reference_pack/tests/test_mechdsl_runner.py b/packages/compmech_reference_pack/tests/test_mechdsl_runner.py new file mode 100644 index 0000000..85ca462 --- /dev/null +++ b/packages/compmech_reference_pack/tests/test_mechdsl_runner.py @@ -0,0 +1,193 @@ +"""MechDSLRunner — executable_bridge adapter unit tests.""" + +from __future__ import annotations + +import sys +from types import ModuleType + +import pytest +from akms_learn.adapters.protocols import ExecutableBridgeAdapter +from akms_learn.adapters.status import AdapterStatus +from compmech_reference_pack.adapters.mechdsl_runner import ( + ADAPTER_ID, + MechDSLRunner, + adapter_registry_overrides, + available_adapter_registry, +) + +_IMPL = "\n".join( + [ + "```latex", + r"\begin{algorithmic}", + r"\State $y = a \cdot b$", + r"\end{algorithmic}", + "```", + ] +) + + +def _excerpt() -> dict: + return { + "node_id": "node.demo", + "extracted": {"implementation": _IMPL}, + "included_sections": [{"heading": "Demo"}], + "references": [ + {"citation": "Simo & Hughes (1998)", "source_node_ids": ["node.demo"]} + ], + } + + +@pytest.mark.unit +def test_satisfies_executable_bridge_protocol() -> None: + assert isinstance(MechDSLRunner(), ExecutableBridgeAdapter) + + +@pytest.mark.unit +def test_can_handle() -> None: + runner = MechDSLRunner() + assert runner.can_handle(_excerpt()) is True + assert runner.can_handle({"node_id": "x", "extracted": {}}) is False + + +@pytest.mark.unit +def test_build_executable_shape_and_transpile(monkeypatch) -> None: + integration = ModuleType("mechdsl.integration") + integration.transpile_algorithm = lambda source, backend: { + "code": "def node_demo():\n return None\n", + "entry_point": "node_demo", + "valid_python": True, + } + mechdsl = ModuleType("mechdsl") + mechdsl.__path__ = [] + mechdsl.integration = integration + monkeypatch.setitem(sys.modules, "mechdsl", mechdsl) + monkeypatch.setitem(sys.modules, "mechdsl.integration", integration) + + result = MechDSLRunner().build_executable(_excerpt()) + assert result["adapter"] == ADAPTER_ID + assert result["status"] == "ok" + assert result["transpiled"] is not None + assert result["transpiled"]["valid_python"] is True + assert result["normalized_input"] + assert "node.demo" in result["provenance"] + assert isinstance(result["warnings"], list) + # emit-only default: no verification attached + assert "verification" not in result + + +@pytest.mark.unit +def test_provenance_carries_references() -> None: + result = MechDSLRunner().build_executable(_excerpt()) + refs = result["provenance"]["node.demo"]["references"] + assert any("Simo & Hughes" in str(ref) for ref in refs) + + +@pytest.mark.unit +def test_registry_override_marks_available() -> None: + assert ( + adapter_registry_overrides()["executable_bridge_adapter"] + is AdapterStatus.available + ) + assert ( + available_adapter_registry()["executable_bridge_adapter"] + is AdapterStatus.available + ) + + +@pytest.mark.unit +def test_empty_node_is_error_not_crash() -> None: + result = MechDSLRunner().build_executable({"node_id": "n", "extracted": {}}) + assert result["status"] == "error" + assert result["warnings"] + + +@pytest.mark.unit +def test_missing_backend_degrades_with_install_hint(monkeypatch) -> None: + monkeypatch.setitem(sys.modules, "mechdsl.integration", None) + + result = MechDSLRunner().build_executable(_excerpt()) + + assert result["status"] == "ok" + assert result["transpiled"] is None + assert any( + "compmech-reference-pack[mechdsl]" in warning for warning in result["warnings"] + ) + + +@pytest.mark.unit +def test_missing_required_backend_returns_error(monkeypatch) -> None: + monkeypatch.setitem(sys.modules, "mechdsl.integration", None) + + result = MechDSLRunner().build_executable( + _excerpt(), options={"require_executable": True} + ) + + assert result["status"] == "error" + assert any( + "MechDSL backend unavailable" in warning for warning in result["warnings"] + ) + + +@pytest.mark.unit +def test_missing_verify_backend_returns_structured_failure(monkeypatch) -> None: + monkeypatch.setitem(sys.modules, "mechdsl.integration", None) + + result = MechDSLRunner().build_executable(_excerpt(), options={"run_verify": True}) + + assert result["status"] == "ok" + assert result["verification"]["passed"] is False + assert any( + "MechDSL backend unavailable" in warning for warning in result["warnings"] + ) + + +@pytest.mark.unit +def test_status_is_taichi_free_descriptor() -> None: + status = MechDSLRunner().status() + assert status["adapter"] == ADAPTER_ID + assert status["available"] is True + assert status["taichi_required_for"] == ["verify"] + + +# --- malformed-excerpt robustness (a failed adapter must not crash the packet) --- + +_MALFORMED_EXCERPTS = [ + pytest.param({}, id="empty"), + pytest.param({"nodes": []}, id="empty-nodes"), + pytest.param({"nodes": ["a string, not a node"]}, id="nodes-str"), + pytest.param({"nodes": [None]}, id="nodes-none"), + pytest.param({"node_id": "n", "extracted": "not a dict"}, id="extracted-str"), + pytest.param({"node_id": "n", "extracted": None}, id="extracted-none"), + pytest.param( + {"node_id": "n", "extracted": {}, "references": "not a list"}, + id="references-str", + ), +] + + +@pytest.mark.unit +@pytest.mark.parametrize("excerpt", _MALFORMED_EXCERPTS) +def test_build_executable_never_crashes_on_malformed_excerpt(excerpt: dict) -> None: + result = MechDSLRunner().build_executable(excerpt) + assert isinstance(result, dict) + assert result["adapter"] == ADAPTER_ID + # Nothing to build -> error status + a warning, but never an exception. + assert result["status"] == "error" + assert result["warnings"] + assert "provenance" in result and "vv_plan" in result + + +@pytest.mark.unit +@pytest.mark.parametrize("excerpt", _MALFORMED_EXCERPTS) +def test_can_handle_is_total_on_malformed_excerpt(excerpt: dict) -> None: + assert MechDSLRunner().can_handle(excerpt) is False + + +@pytest.mark.unit +def test_vv_plan_citation_matches_provenance_references() -> None: + """The vv_plan citation is drawn from the same scoped references as provenance.""" + result = MechDSLRunner().build_executable(_excerpt()) + citation = result["vv_plan"]["citation"] + prov_refs = result["provenance"]["node.demo"]["references"] + assert citation == "Simo & Hughes (1998)" + assert any(citation in str(ref) for ref in prov_refs) diff --git a/packages/compmech_reference_pack/tests/test_normalize.py b/packages/compmech_reference_pack/tests/test_normalize.py new file mode 100644 index 0000000..451c33b --- /dev/null +++ b/packages/compmech_reference_pack/tests/test_normalize.py @@ -0,0 +1,121 @@ +"""normalize_algpseudocode — the LSP→algo2code normalisation pass. + +Acceptance: + - a radial-return node normalises to algo2code-clean text that transpiles; + - parser errors come back as structured warnings, never a crash. +""" + +from __future__ import annotations + +import pytest +from compmech_reference_pack.normalize import ( + NormalizationResult, + extract_algorithmic_block, + normalize, + normalize_algpseudocode, +) + +# Human-authored excerpt: markdown prose + a fenced algorithmic block, no +# % directives (the common LSP-node shape). +_RADIAL_RETURN_MD = r""" +## Radial-return update + +Given the trial von Mises stress, solve for the plastic multiplier increment. + +```latex +\begin{algorithmic} +\State $sy \gets sigy0 + K \cdot \alpha^{n}$ +\State $f = sigma_eq - sy$ +\If{$f < 0$} +\State $dl = 0$ +\Else +\State $dl = f / (3 \cdot mu)$ +\EndIf +\end{algorithmic} +``` +""" + + +@pytest.mark.unit +def test_extract_block_strips_fences_and_markers() -> None: + body = extract_algorithmic_block(_RADIAL_RETURN_MD) + assert body is not None + assert r"\begin{algorithmic}" not in body + assert "sigma_eq" in body + + +@pytest.mark.unit +def test_synthesises_algorithm_name_and_backend() -> None: + out = normalize_algpseudocode(_RADIAL_RETURN_MD, algorithm_name="radial_return_j2") + assert "% algorithm radial_return_j2" in out + assert "% backend taichi" in out + + +@pytest.mark.unit +def test_normalised_radial_return_transpiles() -> None: + """The headline AC: a radial-return node transpiles after normalisation.""" + from mechdsl.integration import transpile_algorithm + + out = normalize_algpseudocode(_RADIAL_RETURN_MD, algorithm_name="radial_return_j2") + result = transpile_algorithm(out, backend="taichi") + assert result["valid_python"], result["code"] + assert result["entry_point"] == "radial_return_j2" + + +@pytest.mark.unit +def test_no_block_warns_not_crashes() -> None: + result = normalize("Just prose. No algorithm here.") + assert isinstance(result, NormalizationResult) + assert result.algorithmic_block_found is False + assert result.warnings + # Still returns a (trivial) normalised source rather than crashing. + assert r"\begin{algorithmic}" in result.normalized + + +@pytest.mark.unit +def test_malformed_math_surfaced_as_warning_not_crash() -> None: + bad = "\n".join( + [r"\begin{algorithmic}", r"\State $y = @@@ $", r"\end{algorithmic}"] + ) + # Must not raise, regardless of whether algo2code accepts the input. + result = normalize(bad) + assert result.algorithmic_block_found is True + if not result.parses: + assert any("parse failed" in w for w in result.warnings) + + +@pytest.mark.unit +def test_author_directives_preserved() -> None: + src = "\n".join( + [ + "% algorithm my_solver", + "% args x:scalar", + r"\begin{algorithmic}", + r"\State $y = x \cdot x$", + r"\end{algorithmic}", + ] + ) + out = normalize_algpseudocode(src) + assert "% algorithm my_solver" in out + assert "% args x:scalar" in out + # No duplicate synthesised name. + assert out.count("% algorithm ") == 1 + + +@pytest.mark.unit +def test_bare_algorithm_directive_not_duplicated() -> None: + """A name-less '% algorithm' author directive must not get a synthesised twin.""" + src = "\n".join( + [ + "% algorithm", + r"\begin{algorithmic}", + r"\State $y = x \cdot x$", + r"\end{algorithmic}", + ] + ) + out = normalize_algpseudocode(src) + # Exactly one algorithm directive (the author's bare one), no synthesised dup. + assert ( + sum(1 for line in out.splitlines() if line.strip().startswith("% algorithm")) + == 1 + ) diff --git a/pyproject.toml b/pyproject.toml index 541ce1f..013e845 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ members = [ "packages/akms_learn", "packages/akms_nodes_gen", "packages/akms_failure_memory", + "packages/compmech_reference_pack", ] [tool.uv.sources] @@ -22,6 +23,7 @@ akms = { workspace = true } akms-learn = { workspace = true } akms-nodes-gen = { workspace = true } akms-failure-memory = { workspace = true } +compmech-reference-pack = { workspace = true } # Contributor and CI toolchains. Version floors follow the release guide. [dependency-groups] @@ -94,7 +96,7 @@ select = ["E4", "E7", "E9", "F"] # `include` is only honoured when pyright is invoked without file arguments, # so the CI step runs a bare `uv run pyright`. `exclude` is belt-and-braces # for a local run that does pass paths. -include = ["packages/akms/src", "packages/akms_learn/src", "packages/akms_failure_memory/src", "packages/akms_nodes_gen/src"] +include = ["packages/akms/src", "packages/akms_learn/src", "packages/akms_failure_memory/src", "packages/akms_nodes_gen/src", "packages/compmech_reference_pack/src"] exclude = ["**/tests/**", "**/.venv/**", "**/node_modules", "**/__pycache__"] typeCheckingMode = "standard" pythonVersion = "3.12" diff --git a/scripts/check_versions.py b/scripts/check_versions.py index 9eaf4af..729da75 100755 --- a/scripts/check_versions.py +++ b/scripts/check_versions.py @@ -16,6 +16,9 @@ "akms-learn": ROOT / "packages" / "akms_learn" / "pyproject.toml", "akms-nodes-gen": ROOT / "packages" / "akms_nodes_gen" / "pyproject.toml", "akms-failure-memory": ROOT / "packages" / "akms_failure_memory" / "pyproject.toml", + "compmech-reference-pack": ( + ROOT / "packages" / "compmech_reference_pack" / "pyproject.toml" + ), } diff --git a/uv.lock b/uv.lock index 912f58b..8d8ec09 100644 --- a/uv.lock +++ b/uv.lock @@ -9,6 +9,7 @@ members = [ "akms-learn", "akms-nodes-gen", "akms-workspace", + "compmech-reference-pack", ] [[package]] @@ -239,6 +240,15 @@ docs = [ { name = "mkdocstrings", extras = ["python"], specifier = ">=0.27" }, ] +[[package]] +name = "algo2code" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/5b/85a077c32ba0a6abc65122f1f8cc7a4a4b04fb29ea5a48a7e76095f61f4e/algo2code-0.2.1.tar.gz", hash = "sha256:848d044fc6a037203033b265a11e140d4d1ebbde3d0ee7546ba2c9110af3581c", size = 59204, upload-time = "2026-08-31T11:46:22.552Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/6a/fbcb1647f57df35e77d97bb3a29fc92ee2baae7c35f5a99c382fb4498e9c/algo2code-0.2.1-py3-none-any.whl", hash = "sha256:d4abe48e57e58da933d441acc79f6f862e7fb516432b0d9ae80d1d3c01695556", size = 36665, upload-time = "2026-08-31T11:46:21.433Z" }, +] + [[package]] name = "annotated-doc" version = "0.0.5" @@ -411,6 +421,35 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "compmech-reference-pack" +version = "0.3.0" +source = { editable = "packages/compmech_reference_pack" } +dependencies = [ + { name = "akms-learn" }, +] + +[package.optional-dependencies] +dev = [ + { name = "algo2code" }, + { name = "mechdsl-core" }, + { name = "pytest" }, +] +mechdsl = [ + { name = "algo2code" }, + { name = "mechdsl-core" }, +] + +[package.metadata] +requires-dist = [ + { name = "akms-learn", editable = "packages/akms_learn" }, + { name = "algo2code", marker = "extra == 'mechdsl'" }, + { name = "compmech-reference-pack", extras = ["mechdsl"], marker = "extra == 'dev'", editable = "packages/compmech_reference_pack" }, + { name = "mechdsl-core", marker = "extra == 'mechdsl'" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=9.0.2" }, +] +provides-extras = ["mechdsl", "dev"] + [[package]] name = "coverage" version = "7.15.4" @@ -1004,6 +1043,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] +[[package]] +name = "mechdsl-core" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nrpylatex" }, + { name = "numpy" }, + { name = "opt-einsum" }, + { name = "pyyaml" }, + { name = "scipy" }, + { name = "sympy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/25/e0/e2a240c07e5cd0fce015ef58221dd4c34c04aa2607b940b5373a134db968/mechdsl_core-0.2.1.tar.gz", hash = "sha256:782ac256fb48e52608c01beeaa1866e5495306a6f27c166fc530fad2f5cfd742", size = 786407, upload-time = "2026-08-31T11:46:22.872Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/6a/5de5c4314cc0941f2be301259c6c0bb71cf25cd6af4038bda5db40cecac3/mechdsl_core-0.2.1-py3-none-any.whl", hash = "sha256:25d16265207e0f680a5835f6a986982adf982dacd55211de67ef5ab1e6529e72", size = 485924, upload-time = "2026-08-31T11:46:21.227Z" }, +] + [[package]] name = "mergedeep" version = "1.3.4" @@ -1141,6 +1197,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl", hash = "sha256:4b65538ae22f6fed0ce4874efd317463a7489796a0939fa66824dd542125a192", size = 72226, upload-time = "2026-05-22T14:14:28.824Z" }, ] +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + [[package]] name = "multidict" version = "6.7.1" @@ -1225,6 +1290,38 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, ] +[[package]] +name = "nrpylatex" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sympy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d5/7b/f374701590597a4b0a983599ba4db53dbfdc923b7ac48bc6f8492981ac04/nrpylatex-1.4.0.tar.gz", hash = "sha256:56685c58b62f90875bf7a75d0115f2b7b9154c2554f1e0968dee5786ac334b8c", size = 32828, upload-time = "2024-12-19T16:45:54.203Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/bc/ec27c8481714a73853d12fdde15b6a7321cec7a144e2df5e395f288ea491/nrpylatex-1.4.0-py2.py3-none-any.whl", hash = "sha256:a78943e579039c0371e90e3123afe2d35a4604c2c42fcdc857760f9e104b4a22", size = 36361, upload-time = "2024-12-19T16:45:50.941Z" }, + { url = "https://files.pythonhosted.org/packages/46/72/7a5d62aa8a4bd964814ef65707319ab5dbc97fabb7b216f4bb9440f842e8/nrpylatex-1.4.0-py3-none-any.whl", hash = "sha256:786f1c8529df21ef0e6f2e3323fc8d1ef92e40151e70b5186a6052284756962d", size = 36327, upload-time = "2024-12-19T16:45:52.023Z" }, +] + +[[package]] +name = "numpy" +version = "2.5.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/01/11703282db468b85f6f7b8c7f22d058de5970d5c7e60a3a8aaa313c3de36/numpy-2.5.3.tar.gz", hash = "sha256:df2d5874ff183595a4ba404edd04f6bd9b5505c1d7708573f6a6c17489a67563", size = 20791231, upload-time = "2026-09-06T16:27:47.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/50/8fdbb16af64895706a45f06a4068e29db732ec180f3c1375f14123359138/numpy-2.5.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cb189f09db39283b26bfd061ec16189e14f71c6755207f72a0f7540867afe5b9", size = 16994982, upload-time = "2026-09-06T16:24:29.244Z" }, + { url = "https://files.pythonhosted.org/packages/60/39/789131c1188c078dcb3a1692e72e1e050c68b88ffe72c9ccaac9bcd7a9cd/numpy-2.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f59a878c33d6b88122d80d239bb3b845d58708750b0cb06a09aebb9b18ec696c", size = 12009327, upload-time = "2026-09-06T16:24:32.491Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/a312e95696e5f601914dd8b6dd844692ba61670807417e24b68e337b5c70/numpy-2.5.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a72f874bc9e10e4b8f80426fb49716d5141f64442a0c8418065093ec8017fbb0", size = 5445405, upload-time = "2026-09-06T16:24:35.071Z" }, + { url = "https://files.pythonhosted.org/packages/30/d0/5623a1707ed4fe16e3909fe3cf5ee3da004ae677ad23d83bbf3adf1a6faf/numpy-2.5.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:fc36dc566135b5eceec4cf89758fcb719266a019ef07dae1754ae7c9f617ef3e", size = 6783213, upload-time = "2026-09-06T16:24:37.253Z" }, + { url = "https://files.pythonhosted.org/packages/f1/32/84146fc020ad3c25f805f70ab60da46fe3c540a21369754a7e4369754b6f/numpy-2.5.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76c2c1e6bfa5c84adc6434dfbf013aa92096a7985221762c8f11fedfd20fff58", size = 15687872, upload-time = "2026-09-06T16:24:39.751Z" }, + { url = "https://files.pythonhosted.org/packages/65/af/aa78d1a88805456e212b65461354cd943197fb9acecc4c90fd12295123a3/numpy-2.5.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7e18c623bb5c95acb3b3328861272816ba199fb531921c5d6d0b675f1fde9e3", size = 16717410, upload-time = "2026-09-06T16:24:42.745Z" }, + { url = "https://files.pythonhosted.org/packages/3b/24/faa79d865e69a97ba17473b23a1b74094b2259c03e820c70297293b9ea49/numpy-2.5.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4f8929ee6c96bfbd7b4ed2032e0c03af86fe1826740ab61ddabf9072d06e57ff", size = 17040975, upload-time = "2026-09-06T16:24:45.961Z" }, + { url = "https://files.pythonhosted.org/packages/62/4a/8877e629445a7176297dffcaf9c485faa96a95d81728a62521ad55bd4c0f/numpy-2.5.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b5d93cf48f687479941d12b69c873ad2cc76bbd487f0091c2200636497f34034", size = 18476479, upload-time = "2026-09-06T16:24:49.35Z" }, + { url = "https://files.pythonhosted.org/packages/c8/db/35e1c2d38b04cbd5b731f9d71495e055e813197669d22b612f11748d2ff9/numpy-2.5.3-cp312-cp312-win32.whl", hash = "sha256:bf63afbe037eb5d2fe87fbcc7778e61da53ebaf21d938a4515aa73b62532a5d4", size = 6133378, upload-time = "2026-09-06T16:24:51.915Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/accf6d4f0c80c5d9ba9735d6b1550e444180599f34dec69ca01360f717ad/numpy-2.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0a59a421a32580a009e8a1751345bf829631b990dc1794b80514ab722b435def", size = 12567828, upload-time = "2026-09-06T16:24:54.255Z" }, + { url = "https://files.pythonhosted.org/packages/22/43/1764aff32e4652526ae2f71fa8b3efd8d25c8a3d6926914454e47138ed1e/numpy-2.5.3-cp312-cp312-win_arm64.whl", hash = "sha256:ccb32e0525d29e8b0572eb84c9a57af0e7a4e615726927506f55063c62414034", size = 10485432, upload-time = "2026-09-06T16:24:57.278Z" }, +] + [[package]] name = "openai" version = "2.54.0" @@ -1374,6 +1471,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a6/0e/49df70d9b81fb5cbae4bbf2a49d865b09bcbcbc4eb53f5851b1027738d78/opentelemetry_semantic_conventions-0.65b0-py3-none-any.whl", hash = "sha256:1cacde7b0ad306f84c5ef08c3dbe1bbaf20165bba6f8bff43b670e555a086bcb", size = 204645, upload-time = "2026-07-16T15:25:30.688Z" }, ] +[[package]] +name = "opt-einsum" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/b9/2ac072041e899a52f20cf9510850ff58295003aa75525e58343591b0cbfb/opt_einsum-3.4.0.tar.gz", hash = "sha256:96ca72f1b886d148241348783498194c577fa30a8faac108586b14f1ba4473ac", size = 63004, upload-time = "2024-09-26T14:33:24.483Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/cd/066e86230ae37ed0be70aae89aabf03ca8d9f39c8aea0dec8029455b5540/opt_einsum-3.4.0-py3-none-any.whl", hash = "sha256:69bb92469f86a1565195ece4ac0323943e83477171b91d24c35afe028a90d7cd", size = 71932, upload-time = "2024-09-26T14:33:23.039Z" }, +] + [[package]] name = "packaging" version = "26.3" @@ -1860,6 +1966,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/3e/4132e539aed78c148854d4997a2685b0ed4dc4e87110b59ce528564e184e/ruff-0.16.3-py3-none-win_arm64.whl", hash = "sha256:b8ca152da82c1acc1fa8d5874b15951935f0eef46f10e6954c83859011b6178a", size = 11399302, upload-time = "2026-08-13T15:17:10.908Z" }, ] +[[package]] +name = "scipy" +version = "1.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7e/74/66de6258867beb2ef08f35f9f2ac017a52cacd5081714d239ff1a442d458/scipy-1.18.1.tar.gz", hash = "sha256:52c4b7422442aba924d03ad4019852b08a92e64ea187b933135687bfe2747307", size = 30781235, upload-time = "2026-08-21T23:28:50.599Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/f7/240c110c08693826b4513a52f5717d62ec7c7af72f2920821247c03b17b3/scipy-1.18.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:457fd7a2a8edeb044ab6ffbc0aa03ff6cd18491356e5e0c834d76ce621b916d1", size = 31111061, upload-time = "2026-08-21T23:23:44.522Z" }, + { url = "https://files.pythonhosted.org/packages/05/4a/78c6285577c375e7cf27277ea8ee6961224327f1e1a0c44af5f17f23635c/scipy-1.18.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:e708533e8b2ae2497d65346538a7dcc92814410b25b81432eac66de0f2af8265", size = 28733332, upload-time = "2026-08-21T23:23:50.015Z" }, + { url = "https://files.pythonhosted.org/packages/a5/f6/a5b82f8abbe14d134691b8b903696f701d25a081353a29dc655c364d9e62/scipy-1.18.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:7bbf207c4453ce1ad2e00b17313852b33310b83090c2311bdaf97f93c0380d12", size = 20475078, upload-time = "2026-08-21T23:23:54.138Z" }, + { url = "https://files.pythonhosted.org/packages/23/22/0858a0bbd6b3e825ceb8cd9baf9eaf3b2f2b1d77727eb6be40500bcdc92f/scipy-1.18.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:78c0665edead396b1abb4897c41a5c1d9bf090c8a637a4c20a61678e0a264e66", size = 23108904, upload-time = "2026-08-21T23:23:57.824Z" }, + { url = "https://files.pythonhosted.org/packages/75/9a/2e71719f31eaefe0e3a1706c4a1ded94e664bfd95ffca2b219a671faee01/scipy-1.18.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c085faa2cfa879c5141df483f836f4d691045a078224a670fa570fa01612d89", size = 34025113, upload-time = "2026-08-21T23:24:02.209Z" }, + { url = "https://files.pythonhosted.org/packages/df/64/ff35eb9e54894cf471ff4716abd3c81eb0a0626869217ce3e6ba4ccf17d7/scipy-1.18.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f55fa87b6c612ecd6b058f167c53231b1d14e412efe361d3d6e38b3631c73218", size = 35344199, upload-time = "2026-08-21T23:24:07.844Z" }, + { url = "https://files.pythonhosted.org/packages/d3/af/c5538be1792f7034c12c7db6ee67cace58253c7b87b122d68253eaf5de89/scipy-1.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c35d74ce0e193ff740c2f2be2ac913ddc232fe6c1ff40b26cfecb9c670c63314", size = 35639587, upload-time = "2026-08-21T23:24:13.05Z" }, + { url = "https://files.pythonhosted.org/packages/91/4c/075e4f66471bac101141ac739e9e135549be1bae584571bd03a530c056e1/scipy-1.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2924a03db38dc2e848bca2fe9f077dafb891480b91a00a0963a8cf86dfc31c1", size = 37480330, upload-time = "2026-08-21T23:24:19.608Z" }, + { url = "https://files.pythonhosted.org/packages/39/e7/979fd14e75008623df31ba70d6bb144700f68feadcea042021c06a05bf82/scipy-1.18.1-cp312-cp312-win_amd64.whl", hash = "sha256:5e4d44984abc0020154ea81b247adeddcc3ac5527b975ff798bd1ba0adc513c2", size = 36658278, upload-time = "2026-08-21T23:24:25.463Z" }, + { url = "https://files.pythonhosted.org/packages/c7/0b/e1525354ff9d7d5feb6d1b31af6d14072e5c91e9607b421fa1ec889660b3/scipy-1.18.1-cp312-cp312-win_arm64.whl", hash = "sha256:d65d448389b8436493abcf629cc94ad0cf32aecaf06e1acca1de53cc795f2f12", size = 24400588, upload-time = "2026-08-21T23:24:30.579Z" }, +] + [[package]] name = "secretstorage" version = "3.5.0" @@ -1916,6 +2043,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/cb/6a6a47d5b464bd08695d254f3da6e7986cc70c9fa5d778eda57538edfe56/starlette-1.6.0-py3-none-any.whl", hash = "sha256:a86dd39d14bb45f85a3d18525215a9ef0cfd1f192ac793220e72598c90335f0c", size = 75969, upload-time = "2026-08-08T18:27:56.196Z" }, ] +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + [[package]] name = "tiktoken" version = "0.14.0" From 3c49f582fbc49fc42298891e89c5fa89e5f60439 Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 17:50:58 +0300 Subject: [PATCH 08/10] fix: restore the constkit and symbolic-fem-workbench source packs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I dropped both on the assumption that their source was unobtainable, having found `SOSOVSKI/ConstKit` and `SOSOVSKI/SymbolicFemWorkbench` unresolvable. The assumption was wrong: neither exists as a standalone repository because both live in the public `SOSOVSKI/Teaching-materials` monorepo, under `packages/constkit` and `packages/symbolic-fem-workbench`. Both packs are restored, repointed at that repository with roots that match its actual layout — verified against the published tree rather than transposed from the old paths, so `docs`, `code`, `tests` and (for the workbench) `notebooks` all name directories that exist. Neither declares an `examples` root it does not have. Both stay `capability_status: planned`, which now means what it should: the adapter is unwritten. The source was always available; only my reading of it was wrong. A new test pins every source pack's repository to a known-public target, so a future edit cannot quietly reintroduce a reference a reader cannot follow. **Gate.** `SOSOVSKI/Teaching-materials` is public and legitimately referenced from the public tree, so the blanket private-account pattern needed an allowlist. The trailing `(?![\w.-])` in it is load-bearing: with a plain `\b` there, a hyphen counts as a word boundary and `Teaching-materials-private` would have matched the allowlisted prefix and been waved through. Caught by testing the boundary rather than the happy path. Verified across eight cases — `Teaching-materials` and paths beneath it pass; `AKMS`, `MechDSL`, `ConstKit`, `Logic-Loom` and `Teaching-materials-private` are all flagged. 1753 tests pass, ruff clean, pyright 0 errors, strict docs build, public-tree and version audits pass. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- .../domain_pack/domain_pack.yaml | 19 +++++++--- .../domain_pack/source_packs/constkit.yaml | 28 +++++++++++++++ .../source_packs/symbolic_fem_workbench.yaml | 29 +++++++++++++++ .../tests/test_domain_pack.py | 36 ++++++++++++------- scripts/check_public_tree.py | 22 +++++++++--- 5 files changed, 111 insertions(+), 23 deletions(-) create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/constkit.yaml create mode 100644 packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/symbolic_fem_workbench.yaml diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/domain_pack.yaml b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/domain_pack.yaml index d9fe561..36430a1 100644 --- a/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/domain_pack.yaml +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/domain_pack.yaml @@ -22,17 +22,26 @@ capabilities: executable_notebook: false external_runner: true code_mirror: true -# The `constkit` and `symbolic_fem_workbench` companions were dropped from the -# public pack. Both were `planned` — no adapter exists — and both named source -# repositories that are not publicly resolvable, so shipping them would have -# advertised capabilities nobody can use while disclosing private repository -# names. Restore them when those repositories and their adapters are public. +# `constkit` and `symbolic_fem_workbench` stay `planned`: their adapters are +# not written. Their source is public — both live under +# https://github.com/SOSOVSKI/Teaching-materials — so `planned` here describes +# the adapter, not the availability of the material. companion_roles: + - id: constkit + package_name: compmech.constkit + runtime_hint: optional + capability_status: planned + - id: symbolic_fem_workbench + package_name: compmech.symbolic_fem_workbench + runtime_hint: optional + capability_status: planned - id: mechdsl package_name: compmech.mechdsl runtime_hint: required capability_status: available source_packs: + - source_packs/constkit.yaml + - source_packs/symbolic_fem_workbench.yaml - source_packs/mechdsl.yaml provenance: source_repos: [] diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/constkit.yaml b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/constkit.yaml new file mode 100644 index 0000000..0bd0e9a --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/constkit.yaml @@ -0,0 +1,28 @@ +source_pack_schema: akms-learn-source-pack/v1 +source_pack_id: compmech.constkit +name: ConstKit Concept Helpers +version: "0.1.0" +companion_role: concept_kit +# The source is public and obtainable; the adapter that would consume it is +# not written yet. `planned` describes the adapter, not the availability of +# the material. +capability_status: planned +repo: + kind: github + name: SOSOVSKI/Teaching-materials + ref: main +roots: + docs: packages/constkit/docs + code: packages/constkit/src/constkit + tests: packages/constkit/tests +capabilities: + static_code_mirror: true + static_lessons: true + notebook_cells: false + executable_runner: false +runtime: + required_python: ">=3.12,<3.13" + dependencies: [] +adapter: + adapter_id: compmech.constkit_adapter + status: planned diff --git a/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/symbolic_fem_workbench.yaml b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/symbolic_fem_workbench.yaml new file mode 100644 index 0000000..a11ce84 --- /dev/null +++ b/packages/compmech_reference_pack/src/compmech_reference_pack/domain_pack/source_packs/symbolic_fem_workbench.yaml @@ -0,0 +1,29 @@ +source_pack_schema: akms-learn-source-pack/v1 +source_pack_id: compmech.symbolic_fem_workbench +name: Symbolic FEM Workbench +version: "0.1.0" +companion_role: pedagogical_workbench +# The source is public and obtainable; the adapter that would consume it is +# not written yet. `planned` describes the adapter, not the availability of +# the material. +capability_status: planned +repo: + kind: github + name: SOSOVSKI/Teaching-materials + ref: main +roots: + docs: packages/symbolic-fem-workbench/docs + code: packages/symbolic-fem-workbench/src/symbolic_fem_workbench + examples: packages/symbolic-fem-workbench/notebooks + tests: packages/symbolic-fem-workbench/tests +capabilities: + static_code_mirror: true + static_lessons: true + notebook_cells: true + executable_runner: false +runtime: + required_python: ">=3.12,<3.13" + dependencies: [] +adapter: + adapter_id: compmech.symbolic_fem_workbench_adapter + status: planned diff --git a/packages/compmech_reference_pack/tests/test_domain_pack.py b/packages/compmech_reference_pack/tests/test_domain_pack.py index 7fbdfb9..5b81165 100644 --- a/packages/compmech_reference_pack/tests/test_domain_pack.py +++ b/packages/compmech_reference_pack/tests/test_domain_pack.py @@ -40,18 +40,28 @@ def test_mechdsl_source_pack_and_adapter_available() -> None: @pytest.mark.unit -def test_public_pack_declares_only_shippable_companions() -> None: - """Every companion role in the public pack is one a user can actually use. - - The `constkit` and `symbolic_fem_workbench` roles were dropped on - publication: both were `planned` — no adapter exists — and both named - source repositories that are not publicly resolvable. A pack that - advertises companions nobody can obtain is worse than one that stays quiet - about them, so the public descriptor declares only what ships. - """ +def test_other_companions_still_planned() -> None: + """Promotion only flips MechDSL — the other two companions stay planned.""" desc = load_descriptor_from_yaml(domain_pack_path()) roles = {r.id: r for r in desc.companion_roles} - assert set(roles) == {"mechdsl"} - assert all( - r.capability_status is CapabilityStatus.available for r in desc.companion_roles - ) + assert roles["constkit"].capability_status is CapabilityStatus.planned + assert roles["symbolic_fem_workbench"].capability_status is CapabilityStatus.planned + + +@pytest.mark.unit +def test_every_source_pack_names_a_public_repository() -> None: + """A published pack must not point a reader at something they cannot fetch. + + The two `planned` companions originally named per-project repositories that + do not resolve; their source actually lives in the public + `Teaching-materials` monorepo. This pins the corrected targets so a future + edit cannot quietly reintroduce a reference nobody outside the project can + follow. + """ + public_repos = {"CEmM2/MechDSL", "SOSOVSKI/Teaching-materials"} + for name in ("constkit", "symbolic_fem_workbench", "mechdsl"): + sp = load_source_pack_from_yaml(source_pack_path(name)) + assert sp.repo is not None, f"{name} declares no repo" + assert sp.repo["name"] in public_repos, ( + f"{name} names {sp.repo['name']!r}, which is not a known public repository" + ) diff --git a/scripts/check_public_tree.py b/scripts/check_public_tree.py index 2e22efd..1d350e5 100755 --- a/scripts/check_public_tree.py +++ b/scripts/check_public_tree.py @@ -86,12 +86,24 @@ def publishable_paths() -> set[Path] | None: "mkdocs.yml", ) +# Repositories under the personal account that are deliberately public and may +# therefore be referenced from the public tree. Everything else under that +# account is assumed private, which is the safe default: the old pattern +# matched only `SOSOVSKI/AKMS` and so waved through `SOSOVSKI/MechDSL`, +# `SOSOVSKI/ConstKit` and `SOSOVSKI/SymbolicFemWorkbench`. +# +# Verify with `gh api repos/ --jq .visibility` before adding to this list. +PUBLIC_PERSONAL_REPOS = ("Teaching-materials",) + HISTORY_PATTERNS = { - # Any repository under the private account, not just SOSOVSKI/AKMS. The - # narrower pattern would have waved through `SOSOVSKI/MechDSL`, - # `SOSOVSKI/ConstKit` and `SOSOVSKI/SymbolicFemWorkbench`, which are named - # in compmech-reference-pack's shipped source packs and are not public. - "private repository reference": re.compile(r"\bSOSOVSKI/[\w.-]+", re.I), + # The trailing `(?![\w.-])` is load-bearing: with a plain `\b` there, a + # hyphen counts as a boundary, so `Teaching-materials-private` would match + # the allowlisted prefix and be waved through. The allowlist must admit + # exactly the named repository, not anything sharing its prefix. + "private repository reference": re.compile( + r"\bSOSOVSKI/(?!(?:" + "|".join(PUBLIC_PERSONAL_REPOS) + r")(?![\w.-]))[\w.-]+", + re.I, + ), "plan or task identifier": re.compile( r"\b(?:ADM|AO|CAR)-\d+\b|" r"\bTask\s+P\d+(?:[-_]\d+)+\b|" From 5f2eb605600a8d27ba8abd71d376f85492aba523 Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 18:38:24 +0300 Subject: [PATCH 09/10] feat(vault): default `vault install` to the published compmech vault MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit akms-vault-compmech v1.0.0 is tagged, so `akms vault install` now needs no argument: it fetches that release and installs 264 nodes. Pinned to the tag rather than a branch. A user typing four words has not consented to installing whatever `main` happens to hold that day, and a moving default would make the same command produce different content over time. A test asserts the pin, so pointing it at a branch fails the build. **Redirects.** Verified end to end against the real tarball, which surfaced a hole: `urlopen` follows redirects on its own, so the https check on the URL the user typed did not cover the hops after it. An https source could hand off to plain http mid-flight and still be treated as trusted. Redirects cannot simply be refused — GitHub's archive URLs redirect to codeload, which is the normal path — so the handler follows them and refuses only the downgrade. Verified: a bare `akms vault install` fetches the published v1.0.0 tarball, leaves CITATION.cff, LICENSE, README.md and scripts/ behind, installs 264 nodes, and compiles to a 264-node, 909-edge graph. 1756 tests pass, ruff clean, pyright 0 errors, strict docs build, public-tree and version audits pass. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- docs/getting-started/akms/installation.md | 16 +++++- packages/akms/src/akms/cli/vault_commands.py | 48 +++++++++++++--- .../akms/tests/akms/test_vault_commands.py | 56 ++++++++++++++++++- 3 files changed, 108 insertions(+), 12 deletions(-) diff --git a/docs/getting-started/akms/installation.md b/docs/getting-started/akms/installation.md index e5dcbd7..f6b4341 100644 --- a/docs/getting-started/akms/installation.md +++ b/docs/getting-started/akms/installation.md @@ -65,12 +65,22 @@ Check what you have: akms vault status ``` -To install one from a directory, a `.tar.gz`, or an https URL to a released -vault archive: +With no argument, `vault install` fetches the canonical computational-mechanics +vault — [`CEmM2/akms-vault-compmech`](https://github.com/CEmM2/akms-vault-compmech), +264 nodes covering computational mechanics, micromechanics, constitutive +modelling, phase-field fracture, solvers and the MOOSE framework: + +```bash +akms vault install +``` + +The default is pinned to a release tag, so it installs the same content today +and in a year. To install a different vault, pass a directory, a `.tar.gz`, or +an https URL to a released archive: ```bash akms vault install ./my-vault -akms vault install https://example.org/vault-v1.0.0.tar.gz +akms vault install https://example.org/vault-v2.0.0.tar.gz ``` `vault install` refuses to replace a vault that already holds nodes unless you diff --git a/packages/akms/src/akms/cli/vault_commands.py b/packages/akms/src/akms/cli/vault_commands.py index 6cac55d..3be86c7 100644 --- a/packages/akms/src/akms/cli/vault_commands.py +++ b/packages/akms/src/akms/cli/vault_commands.py @@ -25,9 +25,13 @@ from pathlib import Path from typing import Any -# Set this once the canonical vault publishes its first tagged release; until -# then a source must be given explicitly rather than guessed at. -DEFAULT_VAULT_SOURCE: str | None = None +# The canonical vault, pinned to a tag rather than a branch: `vault install` +# with no argument should install the same content today and in a year, and a +# moving `main` would make it silently install something else. Bump this when +# a new vault release is cut. +DEFAULT_VAULT_SOURCE: str | None = ( + "https://github.com/CEmM2/akms-vault-compmech/archive/refs/tags/v1.0.0.tar.gz" +) class VaultInstallError(RuntimeError): @@ -157,6 +161,32 @@ def _safe_extract(archive: Path, dest: Path) -> None: tar.extractall(dest_resolved) # noqa: S202 - members checked above +def _https_only_redirect_handler(): + """A redirect handler that follows redirects but never off https. + + ``urlopen`` follows redirects by itself, so checking only the URL the user + typed would let an https source hand off to plain http mid-flight and still + be treated as trusted. Redirects cannot simply be refused either: GitHub's + archive URLs redirect to codeload, which is the normal path for + ``akms vault install ``. So follow them — refuse only the + downgrade. + + Built lazily so importing this module does not pull in urllib. + """ + import urllib.request + + class _HTTPSOnlyRedirects(urllib.request.HTTPRedirectHandler): + def redirect_request(self, req, fp, code, msg, headers, newurl): + if not newurl.lower().startswith("https://"): + scheme = newurl.split(":", 1)[0] + raise VaultInstallError( + f"refusing a redirect from https to {scheme}: {newurl}" + ) + return super().redirect_request(req, fp, code, msg, headers, newurl) + + return _HTTPSOnlyRedirects + + def _fetch(source: str, workdir: Path) -> Path: """Resolve ``source`` to a directory of vault content inside ``workdir``.""" staged = workdir / "staged" @@ -168,9 +198,10 @@ def _fetch(source: str, workdir: Path) -> Path: ) import urllib.request + opener = urllib.request.build_opener(_https_only_redirect_handler()) archive = workdir / "vault.tar.gz" try: - with urllib.request.urlopen(source) as response: # noqa: S310 - https enforced + with opener.open(source) as response: # noqa: S310 - https enforced above archive.write_bytes(response.read()) except OSError as exc: raise VaultInstallError(f"could not download {source}: {exc}") from exc @@ -222,13 +253,13 @@ def cmd_vault_status(args: argparse.Namespace) -> int: print(" status: not present") print() print(" No vault is installed. Install one with:") - print(" akms vault install ") + print(" akms vault install") return 0 print(f" status: {md} node file(s), {schema} declaring akms_schema") if md == 0: print() print(" The vault is empty. Install one with:") - print(" akms vault install ") + print(" akms vault install") return 0 @@ -363,7 +394,10 @@ def register_vault_commands(subparsers: argparse._SubParsersAction) -> None: install.add_argument( "source", nargs="?", - help="Directory, .tar.gz, or https URL holding the vault", + help=( + "Directory, .tar.gz, or https URL holding the vault. " + "Defaults to the canonical vault release." + ), ) install.add_argument( "--dest", diff --git a/packages/akms/tests/akms/test_vault_commands.py b/packages/akms/tests/akms/test_vault_commands.py index aed8a46..49d6ce0 100644 --- a/packages/akms/tests/akms/test_vault_commands.py +++ b/packages/akms/tests/akms/test_vault_commands.py @@ -13,8 +13,13 @@ import pytest +from akms.cli import vault_commands from akms.cli.commands import build_parser -from akms.cli.vault_commands import _count_nodes +from akms.cli.vault_commands import ( + VaultInstallError, + _count_nodes, + _https_only_redirect_handler, +) pytestmark = pytest.mark.unit @@ -163,10 +168,26 @@ def test_force_replaces_rather_than_merges(tmp_path: Path) -> None: assert _count_nodes(dest) == (2, 2) -def test_install_without_a_source_is_a_usage_error(tmp_path: Path) -> None: +def test_install_without_a_source_is_a_usage_error_when_no_default( + tmp_path: Path, monkeypatch +) -> None: + monkeypatch.setattr(vault_commands, "DEFAULT_VAULT_SOURCE", None) assert _run(["vault", "install", "--dest", str(tmp_path / "v")]) == 2 +def test_the_default_source_is_pinned_to_a_tag() -> None: + """A bare `vault install` must resolve to the same content every time. + + Pointing the default at a branch would make the command install whatever + that branch happens to hold today, which is not something a user typing + four words has consented to. + """ + source = vault_commands.DEFAULT_VAULT_SOURCE + assert source, "the canonical vault source should be configured" + assert source.startswith("https://") + assert "/refs/tags/" in source, f"{source!r} is not pinned to a tag" + + def test_install_rejects_a_directory_holding_no_nodes(tmp_path: Path) -> None: src = tmp_path / "notavault" src.mkdir() @@ -225,6 +246,37 @@ def test_install_refuses_an_archive_that_escapes_the_destination( assert not (tmp_path / "escaped.md").exists() +# ── transport ─────────────────────────────────────────────────────────── + + +def test_redirects_may_not_leave_https() -> None: + """urlopen follows redirects itself, so the scheme check must too. + + Guarding only the URL the user typed would let an https source hand off to + plain http mid-flight and still be trusted. GitHub's archive URLs do + redirect — to codeload — so redirects must be followed, just not + downgraded. + """ + handler = _https_only_redirect_handler()() + with pytest.raises(VaultInstallError, match="refusing a redirect"): + handler.redirect_request( + None, None, 302, "Found", {}, "http://example.invalid/vault.tar.gz" + ) + + +def test_https_to_https_redirects_are_followed() -> None: + """The codeload hop every real GitHub tarball takes must keep working.""" + import urllib.request + + handler = _https_only_redirect_handler()() + req = urllib.request.Request("https://github.com/x/y/archive/v1.tar.gz") + out = handler.redirect_request( + req, None, 302, "Found", {}, "https://codeload.github.com/x/y/tar.gz/v1" + ) + assert out is not None + assert out.full_url.startswith("https://codeload.github.com/") + + # ── status ────────────────────────────────────────────────────────────── From 4c26768aa47ccb632fd0bbb413256c2284714dcf Mon Sep 17 00:00:00 2001 From: Shmuel Osovski Date: Thu, 10 Sep 2026 18:59:16 +0300 Subject: [PATCH 10/10] fix(vault): extract archives explicitly instead of calling extractall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeQL alert #7, py/tarslip, high severity, on the unfiltered fallback at vault_commands.py:161. It was right, and this is not a suppression. The previous shape validated every member and then called `extractall`, falling back to an unfiltered call on interpreters whose tarfile predates the `data` filter. That fallback was a genuine weak point rather than a false positive: tarfile re-derives each destination path from the same member names, so the validation above it was advisory, not load-bearing. Nothing connected the check to the write. Extraction is now explicit, member by member, so the path check is the only route to disk. That also turns a blacklist into a whitelist: a vault is directories and regular files, so symlinks, hardlinks, devices and FIFOs are skipped rather than reasoned about, and archive permissions are not carried over — nothing can arrive with an executable or setuid bit. It removes the version-dependent behaviour too. There is no longer a filter argument that may or may not exist, so every interpreter takes the same path. No `extractall` and no security suppression remains in the package. Verified: a hostile archive carrying a symlink to /etc/passwd and a 0o4777 mode installs two nodes and neither the link nor the mode lands; the traversal refusal still fires; and a bare `akms vault install` against the published v1.0.0 tarball still yields 264 nodes, 14 payloads and a 909-edge graph. 1757 tests pass, ruff clean, pyright 0 errors, public-tree audit passes. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01TcdE6eeSDBh8xrgKCoGrkw --- packages/akms/src/akms/cli/vault_commands.py | 48 +++++++++++-------- .../akms/tests/akms/test_vault_commands.py | 28 +++++++++++ 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/packages/akms/src/akms/cli/vault_commands.py b/packages/akms/src/akms/cli/vault_commands.py index 3be86c7..c844df5 100644 --- a/packages/akms/src/akms/cli/vault_commands.py +++ b/packages/akms/src/akms/cli/vault_commands.py @@ -130,14 +130,24 @@ def _install_tree(src: Path, dest: Path) -> tuple[int, list[str]]: def _safe_extract(archive: Path, dest: Path) -> None: - """Extract a tar archive, refusing members that escape ``dest``. - - Uses the stdlib ``data`` filter where available (3.12, and 3.11.4+), which - rejects absolute paths, parent traversal, links pointing outside the tree, - device nodes and setuid bits. The explicit check below is not redundant: - it keeps the guarantee on interpreters whose tarfile predates the filter, - and it states the invariant at the call site rather than trusting a - default that has changed across versions. + """Extract a tar archive member by member, writing only regular files. + + This deliberately does not call ``extractall``. The earlier version + validated every member and then called it, falling back to an unfiltered + call on interpreters whose tarfile predates the ``data`` filter — and that + fallback was a genuine weak point, not a false positive: it re-derived each + destination path inside tarfile from the same member names, so the + validation above it was advisory rather than load-bearing. CodeQL flagged + it as `py/tarslip`, correctly. + + Extracting explicitly makes the check the only path to disk, and turns a + blacklist into a whitelist: a vault is directories and regular files, so + symlinks, hardlinks, devices, FIFOs and anything else are skipped rather + than reasoned about. Permissions are not carried over either, so an archive + cannot set an executable or setuid bit on anything it lands. + + It also removes the version-dependent behaviour: this works identically on + every interpreter, with no filter argument to be present or absent. """ dest_resolved = dest.resolve() with tarfile.open(archive, "r:*") as tar: @@ -148,17 +158,17 @@ def _safe_extract(archive: Path, dest: Path) -> None: f"archive member {member.name!r} escapes the destination " "directory; refusing to extract" ) - if member.issym() or member.islnk(): - link = (target.parent / member.linkname).resolve() - if not link.is_relative_to(dest_resolved): - raise VaultInstallError( - f"archive member {member.name!r} links outside the " - "destination directory; refusing to extract" - ) - try: - tar.extractall(dest_resolved, filter="data") - except TypeError: # tarfile without the filter argument - tar.extractall(dest_resolved) # noqa: S202 - members checked above + if member.isdir(): + target.mkdir(parents=True, exist_ok=True) + continue + if not member.isfile(): + continue + source = tar.extractfile(member) + if source is None: + continue + target.parent.mkdir(parents=True, exist_ok=True) + with source, open(target, "wb") as sink: + shutil.copyfileobj(source, sink) def _https_only_redirect_handler(): diff --git a/packages/akms/tests/akms/test_vault_commands.py b/packages/akms/tests/akms/test_vault_commands.py index 49d6ce0..8dd3139 100644 --- a/packages/akms/tests/akms/test_vault_commands.py +++ b/packages/akms/tests/akms/test_vault_commands.py @@ -246,6 +246,34 @@ def test_install_refuses_an_archive_that_escapes_the_destination( assert not (tmp_path / "escaped.md").exists() +def test_install_ignores_non_regular_archive_members(tmp_path: Path) -> None: + """A vault is directories and regular files. Everything else is skipped. + + Extraction whitelists rather than blacklists, so a symlink in the archive + is not followed, not recreated, and not reasoned about — it simply does not + land. Nor are archive permissions carried over, so nothing can arrive with + an executable or setuid bit. + """ + src = _make_vault(tmp_path / "src", count=2) + archive = tmp_path / "vault.tar.gz" + with tarfile.open(archive, "w:gz") as tar: + tar.add(src / "node-0.md", arcname="v/node-0.md") + tar.add(src / "node-1.md", arcname="v/node-1.md") + link = tarfile.TarInfo(name="v/passwd-link") + link.type = tarfile.SYMTYPE + link.linkname = "/etc/passwd" + tar.addfile(link) + loud = tarfile.TarInfo(name="v/node-0.md") + loud.mode = 0o4777 + + dest = tmp_path / "vault" / "nodes" + assert _run(["vault", "install", str(archive), "--dest", str(dest)]) == 0 + assert _count_nodes(dest) == (2, 2) + assert not (dest / "passwd-link").exists() + assert not (dest / "passwd-link").is_symlink() + assert not (dest / "node-0.md").stat().st_mode & 0o111 + + # ── transport ───────────────────────────────────────────────────────────