diff --git a/src/materials/api.jl b/src/materials/api.jl index 32af8a3..79423e8 100644 --- a/src/materials/api.jl +++ b/src/materials/api.jl @@ -17,35 +17,7 @@ Must be included after core api.jl. Abstract type for all material models. -# Interface Requirements - -All material models must implement: -```julia -compute_stress( - material::AbstractMaterial, - ε::SymmetricTensor{2,3,T}, - state_old, - Δt::Float64 -) -> (σ::SymmetricTensor{2,3,T}, 𝔻::SymmetricTensor{4,3,T}, state_new) -``` - -Returns: -- `σ`: Cauchy stress tensor -- `𝔻`: Material tangent (4th-order elasticity tensor) -- `state_new`: Updated material state (for plasticity, damage, etc.) - -# Type Hierarchy -- `AbstractElasticMaterial` - Stateless elastic materials (no history) -- `AbstractPlasticMaterial` - Stateful plastic materials (history-dependent) - -# Design Philosophy - -Materials are immutable structs with parameters (E, ν, etc.). -Material state (plastic strain, damage) stored separately in solution. -Use Tensors.jl for all tensor operations (no Voigt notation). - -# See Also -- Concrete implementations in src/materials/ +All material models must implement `compute_stress(material, ε, state_old, Δt)`. """ abstract type AbstractMaterial end @@ -53,23 +25,6 @@ abstract type AbstractMaterial end AbstractElasticMaterial <: AbstractMaterial Stateless elastic materials (no history variables). - -Elastic materials compute stress directly from strain with no memory of loading history. - -# Characteristics -- No internal state variables -- Reversible deformation -- Path-independent response -- `state_new = state_old` always - -# Examples -- `LinearElastic`: Hooke's law (small strain) -- `NeoHookean`: Hyperelastic (finite strain) -- `Mooney-Rivlin`: Hyperelastic with two parameters -- `Ogden`: Hyperelastic for rubber-like materials - -# See Also -- [`AbstractPlasticMaterial`](@ref) for history-dependent materials """ abstract type AbstractElasticMaterial <: AbstractMaterial end @@ -77,31 +32,6 @@ abstract type AbstractElasticMaterial <: AbstractMaterial end AbstractPlasticMaterial <: AbstractMaterial Stateful plastic materials (history-dependent). - -Plastic materials have internal state variables that evolve with loading history. - -# Characteristics -- Internal state variables (plastic strain, hardening, etc.) -- Irreversible deformation -- Path-dependent response -- `state_new ≠ state_old` during plastic loading - -# Examples -- `PerfectPlasticity`: J2 plasticity with no hardening -- `IsotropicHardening`: J2 plasticity with isotropic hardening -- `KinematicHardening`: Bauschinger effect modeling -- `FiniteStrainPlasticity`: Large deformation plasticity - -# State Variables - -Common state variables: -- `εᵖ`: Plastic strain tensor -- `α`: Backstress (kinematic hardening) -- `κ`: Equivalent plastic strain (isotropic hardening) -- `damage`: Damage parameter (continuum damage mechanics) - -# See Also -- [`AbstractElasticMaterial`](@ref) for stateless materials """ abstract type AbstractPlasticMaterial <: AbstractMaterial end @@ -110,62 +40,14 @@ abstract type AbstractPlasticMaterial <: AbstractMaterial end Abstract type for material internal state at integration points. -Concrete types must be immutable and contain all internal variables -needed for incremental material models (plasticity, damage, etc.). - -# Concrete Types -- `PlasticityState` - J2 plasticity state (εᵖ, α, κ) -- `FiniteStrainPlasticityState` - Multiplicative plasticity state -- Add more as needed for damage, viscoelasticity, etc. - -# Design -States are immutable structs for thread safety. Updates create new instances. - -# Usage -State types are used in: -- `AssemblyMaterialWorkspace{M<:AbstractMaterialState}` - Per-element workspace during assembly -- `GlobalMaterialCache{StateType}` - Persistent state storage for time-stepping [nips, nelems] -- Material `compute_stress` functions for state evolution - -# Examples -```julia -# Define concrete state type -struct PlasticityState <: AbstractMaterialState - εᵖ::SymmetricTensor{2,3,Float64,6} - α::SymmetricTensor{2,3,Float64,6} - κ::Float64 -end - -# Initialize state -state = PlasticityState(zero(SymmetricTensor{2,3}), zero(SymmetricTensor{2,3}), 0.0) - -# Use in compute_stress -σ, 𝔻, state_new = compute_stress(material, ε, state, Δt) -``` - -# See Also -- [`AbstractPlasticMaterial`](@ref) - Materials that use state -- [`AssemblyMaterialWorkspace`](@ref) - Per-element workspace during assembly -- [`GlobalMaterialCache`](@ref) - Persistent state storage for time-stepping -- [`compute_stress`](@ref) - Material constitutive function +Concrete types must be immutable for thread safety. """ abstract type AbstractMaterialState end """ EmptyState <: AbstractMaterialState -Empty material state for stateless materials (e.g., LinearElastic). - -Stateless materials don't need internal state variables, but the type system -requires a concrete `M <: AbstractMaterialState` for `AssemblyMaterialWorkspace{M}`. -`EmptyState` serves as a placeholder that carries no data. - -# Usage -```julia -# LinearElastic uses EmptyState -material = LinearElastic(E=210.0e9, ν=0.3) -workspace = AssemblyMaterialWorkspace{EmptyState}(...) -``` +Empty material state for stateless materials. """ struct EmptyState <: AbstractMaterialState end @@ -180,32 +62,6 @@ Base.zero(::Type{EmptyState}) = EmptyState() MaterialBehavior Abstract type for material behavior traits. - -Material behavior traits allow integration code to query what computational -requirements a material has (constant vs strain-dependent tangent, stateless -vs stateful) without writing material-specific integration functions. - -# Type Hierarchy -- `StatelessConstantTangent` - Tangent is constant (e.g., LinearElastic) -- `StatelessStrainDependent` - Tangent depends on strain (e.g., NeoHookean) -- `StatefulStrainDependent` - Has internal state variables (e.g., PerfectPlasticity) - -# Usage -Each material declares its behavior via: -```julia -material_behavior(::MyMaterial) = StatelessConstantTangent() -``` - -Integration code can then dispatch on behavior: -```julia -behavior = material_behavior(material) -𝔻 = compute_tangent_at_point(material, behavior, ...) -``` - -# See Also -- [`material_behavior`](@ref) - Trait function -- [`needs_deformation`](@ref) - Query if material needs displacement field -- [`needs_state`](@ref) - Query if material has internal state """ abstract type MaterialBehavior end @@ -213,16 +69,6 @@ abstract type MaterialBehavior end StatelessConstantTangent <: MaterialBehavior Material with constant tangent modulus (independent of strain). - -Materials with this behavior: -- Compute tangent once (e.g., at reference strain E=0) -- Reuse same tangent at all integration points -- No displacement field needed during integration -- No internal state variables - -**Examples:** LinearElastic - -**Performance:** Fastest - tangent computed once per element """ struct StatelessConstantTangent <: MaterialBehavior end @@ -230,16 +76,6 @@ struct StatelessConstantTangent <: MaterialBehavior end StatelessStrainDependent <: MaterialBehavior Material with strain-dependent tangent modulus (no internal state). - -Materials with this behavior: -- Tangent depends on current strain/deformation -- Must compute tangent at each integration point -- Requires displacement field to compute deformation gradient F -- No internal state variables (path-independent) - -**Examples:** NeoHookean, Mooney-Rivlin, Ogden - -**Performance:** Moderate - tangent computed at each integration point """ struct StatelessStrainDependent <: MaterialBehavior end @@ -247,17 +83,6 @@ struct StatelessStrainDependent <: MaterialBehavior end StatefulStrainDependent <: MaterialBehavior Material with strain-dependent tangent and internal state variables. - -Materials with this behavior: -- Tangent depends on current strain and state history -- Must compute tangent at each integration point -- Requires displacement field to compute strain -- Has internal state variables (e.g., plastic strain, damage) -- History-dependent (path-dependent) - -**Examples:** PerfectPlasticity, FiniteStrainPlasticity, ContinuumDamage - -**Performance:** Slowest - tangent + state update at each integration point """ struct StatefulStrainDependent <: MaterialBehavior end @@ -265,26 +90,6 @@ struct StatefulStrainDependent <: MaterialBehavior end material_behavior(material::AbstractMaterial) -> MaterialBehavior Trait function declaring what computational requirements a material has. - -# Returns -- `StatelessConstantTangent()` - Constant tangent (e.g., LinearElastic) -- `StatelessStrainDependent()` - Strain-dependent tangent, no state (e.g., NeoHookean) -- `StatefulStrainDependent()` - Strain-dependent tangent + state (e.g., PerfectPlasticity) - -# Examples -```julia -material_behavior(::LinearElastic) = StatelessConstantTangent() -material_behavior(::NeoHookean) = StatelessStrainDependent() -material_behavior(::PerfectPlasticity) = StatefulStrainDependent() -``` - -# Implementation Required -All concrete material types must implement this trait function. - -# See Also -- [`MaterialBehavior`](@ref) - Behavior trait types -- [`needs_deformation`](@ref) - Convenience query -- [`needs_state`](@ref) - Convenience query """ function material_behavior end @@ -292,16 +97,6 @@ function material_behavior end needs_deformation(material::AbstractMaterial) -> Bool Query whether material needs displacement field for tangent computation. - -Returns `true` for materials with strain-dependent tangent, `false` for -materials with constant tangent. - -# Examples -```julia -needs_deformation(LinearElastic(E=210e9, ν=0.3)) # false -needs_deformation(NeoHookean(μ=1e6, λ=1e9)) # true -needs_deformation(PerfectPlasticity(...)) # true -``` """ needs_deformation(mat::AbstractMaterial) = !(material_behavior(mat) isa StatelessConstantTangent) @@ -309,16 +104,6 @@ needs_deformation(mat::AbstractMaterial) = !(material_behavior(mat) isa Stateles needs_state(material::AbstractMaterial) -> Bool Query whether material has internal state variables. - -Returns `true` for stateful materials (plasticity, damage), `false` for -stateless materials (elasticity). - -# Examples -```julia -needs_state(LinearElastic(E=210e9, ν=0.3)) # false -needs_state(NeoHookean(μ=1e6, λ=1e9)) # false -needs_state(PerfectPlasticity(...)) # true -``` """ needs_state(mat::AbstractMaterial) = material_behavior(mat) isa StatefulStrainDependent @@ -326,25 +111,6 @@ needs_state(mat::AbstractMaterial) = material_behavior(mat) isa StatefulStrainDe state_type(::Type{<:AbstractMaterial}) -> Type{<:AbstractMaterialState} Return the concrete state type for a given material type. - -This trait function maps material types to their corresponding state types: -- Stateless materials (elastic) → `EmptyState` -- Stateful materials (plastic) → `PlasticityState` (or other state types) - -# Examples -```julia -state_type(LinearElastic) → EmptyState -state_type(PerfectPlasticity) → PlasticityState -``` - -# Implementation -Materials must define: -```julia -state_type(::Type{PerfectPlasticity}) = PlasticityState -``` - -# Default -By default, materials are stateless (return `EmptyState`). """ state_type(::Type{<:AbstractMaterial}) = EmptyState @@ -357,39 +123,6 @@ state_type(::Type{<:AbstractMaterial}) = EmptyState -> (σ, 𝔻, state_new) Compute stress, tangent, and updated state for a material model. - -# Arguments -- `material`: Material model parameters -- `ε`: Strain tensor (SymmetricTensor{2,3} or similar) -- `state_old`: Previous state (Dict, NamedTuple, or nothing for elastic) -- `Δt`: Time step (for rate-dependent materials) - -# Returns -- `σ`: Cauchy stress tensor -- `𝔻`: Material tangent (∂σ/∂ε) -- `state_new`: Updated internal state - -# Examples - -```julia -# Elastic material (no state) -σ, 𝔻, _ = compute_stress(LinearElastic(E=210e9, ν=0.3), ε, nothing, 0.0) - -# Plastic material (with state) -state = (εᵖ=zero(SymmetricTensor{2,3}), κ=0.0) -σ, 𝔻, state_new = compute_stress(PerfectPlasticity(E=210e9, ν=0.3, σ_y=250e6), - ε, state, Δt) -``` - -# Implementation Notes - -Material models implement this function with specific signatures: -- Elastic: `compute_stress(::LinearElastic, ε, _, _)` -- Plastic: `compute_stress(::PerfectPlasticity, ε, state, Δt)` - -# See Also -- [`elasticity_tensor`](@ref) for elastic constitutive tensor -- Material implementations in src/materials/ """ function compute_stress end @@ -397,33 +130,5 @@ function compute_stress end elasticity_tensor(material::AbstractElasticMaterial) -> Tensor{4,3} Compute 4th-order elasticity tensor for an elastic material. - -For linear elastic material: -``` -C_ijkl = λ δ_ij δ_kl + μ (δ_ik δ_jl + δ_il δ_jk) -``` - -where: -- λ = Eν/((1+ν)(1-2ν)) (Lamé's first parameter) -- μ = E/(2(1+ν)) (shear modulus) - -# Arguments -- `material`: Elastic material with parameters (E, ν, etc.) - -# Returns -- `C`: 4th-order elasticity tensor (Tensor{4,3}) - -# Examples - -```julia -mat = LinearElastic(E=210e9, ν=0.3) -C = elasticity_tensor(mat) - -# Use in stress computation -σ = C ⊡ ε # Double-dot product: σ_ij = C_ijkl ε_kl -``` - -# See Also -- [`compute_stress`](@ref) for full stress computation """ function elasticity_tensor end