Dissipation positivity check - #1771
Open
IvarStefansson wants to merge 5 commits into
Open
Conversation
The states the test prescribes are spatially uniform, so the two agree numerically. The difference is in what is guaranteed: a mean stays positive while individual cells go negative, and the property being checked is pointwise.
Asperities resist being sheared through; they do not assist. The sign matters beyond its own term: mu_p >= 0 is one of the two preconditions under which mu* - tan psi is positive term by term, the other being the pole the sliding composition already guards. Checked where the value is produced rather than where it is used, so the quantity validated is unambiguously the intact coefficient rather than the damage-scaled one.
D = (mu* - tan psi) sigma_n, the shear resistance less the part recovered as dilation. Distinct from the total frictional work mu* sigma_n that drives the wear, which includes the dilational part deliberately. Positivity is an algebraic identity given the two conditions the sliding and ploughing guards check, so a non-positive value means the composition was assembled wrongly rather than that the parameters are marginal.
The frictional dissipation is non-negative by an algebraic identity, so a negative value means the law is composed wrongly rather than that the parameters are extreme. Check it once per converged nonlinear solve and raise, since a fracture that produces energy by sliding invalidates every number in the run. The identity's basic-friction term exceeds tan psi for any realistic mu_b, so it is the term that carries the sign; a mis-ordering costing only the ploughing term stays admissible and is left to the closed-form tests.
Friction resists sliding. The sign matters beyond its own term: mu_b enters the one term of mu* - tan psi large enough to carry the sign, so it is the only parameter that makes a correctly composed law dissipate negatively. Checked alongside the pole, both being parameter-level preconditions of the same sliding composition. This leaves the standing dissipation check guarding the composition and any future state dependence of mu_b or psi_0, rather than the parameters.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Assert dissipation positivity
Stacked on #1768 — the base branch is
dissipation-driven-history, notdevelop.Adds two parameter guards and a runtime check that the frictional dissipation
D = (μ* − tanψ)σ_nis non-negative at every converged solve.What it is for.
μ* − tanψ = μ_b(1 + tan²ψ)/(1 − μ_b tanψ) + μ_pis an algebraic identity, so with admissible parameters the dissipation is non-negative at every reachable state: the clips holdtanψ ≤ tanψ_0, and the guards holdμ_b tanψ_0 < 1,μ_b ≥ 0andμ_p⁰ ≥ 0. The new runtime check therefore cannot fire on parameters. It catches an implementation error, and specifically one that loses or negates theμ_bterm, that being the only term large enough to carry the sign. It also guards a future law in whichμ_borψ_0becomes state dependent, where a pole crossed mid-run would pass a check made once at construction.The check is opt-in, via its own mixin.
constitutive_laws.pytoday contains zero lifecycle-hook overrides — constitutive laws are pure operator providers, and the file's only validation idiom is "evaluate a sub-operator inside the operator-returning method and raise" (_validate_sliding_composition,BartonBandis,SecondOrderTensorUtils). Puttingafter_nonlinear_convergenceonAsperityStressPartitionwould make a law class join the solve lifecycle and would charge every user of the partition for the check. A separate mixin keeps the laws clean and puts "this model asserts its own admissibility" in the base list where a reader sees it.Changes
AsperityStressPartition.frictional_dissipation—(μ* − tanψ)σ_n. Both factors are read throughself, so it is the composed coefficient and the damaged, partitioned dilation angle the model actually uses. Distinct from the total frictional workμ*σ_nthat drives the wear, which includes the dilational part deliberately.μ_p⁰ ≥ 0, validated inploughing_friction_coefficientwhere the value is produced, so that what is checked is unambiguously the intact coefficient rather than the damage-scaled one.μ_b ≥ 0, alongside the existing pole check in_validate_sliding_composition. Both are parameter-level preconditions of the same identity.DissipationPositivityCheck— overridesafter_nonlinear_convergenceand raises, naming the offending cell count, the minimum and its index. Mixed intoFractureDamageMomentumBalance. Zero is admissible and not reported: it is the frictionless limit.Tests
test_dissipation_is_positivetightened from the cell mean to the smallest cell value — identical on the uniform states it prescribes, but a positive mean can hide negative cells. New tests cover the dissipation against a closed form in Pa, the check firing when the basic friction term is removed, the check silent on a correct composition, the frictionless limit accepted, and both parameter guards.Mutation-tested, since a check nobody has made fire is untested scaffolding: dropping the
characteristic_contact_tractionfactor fails the closed-form cases, and the firing test assertsD < 0before expecting the raise so it cannot pass vacuously.The check adds no operator to any equation, so results are unchanged.