mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-25 11:35:30 +00:00
100 lines
3.3 KiB
Julia
100 lines
3.3 KiB
Julia
|
|
# This file is a part of JuliaFEM.
|
|||
|
|
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
|||
|
|
|
|||
|
|
using Test
|
|||
|
|
using JuliaFEM
|
|||
|
|
using Tensors
|
|||
|
|
|
|||
|
|
@testset "Material Traits" begin
|
|||
|
|
@testset "LinearElastic traits" begin
|
|||
|
|
mat = LinearElastic(E=210e9, ν=0.3)
|
|||
|
|
|
|||
|
|
# Test supported_physics
|
|||
|
|
physics = supported_physics(mat)
|
|||
|
|
@test physics isa Tuple
|
|||
|
|
@test length(physics) == 1
|
|||
|
|
@test physics[1] isa Elasticity{3}
|
|||
|
|
|
|||
|
|
# Test required_field_types (derived from supported_physics)
|
|||
|
|
fields = required_field_types(mat)
|
|||
|
|
@test fields isa Tuple
|
|||
|
|
@test length(fields) == 1
|
|||
|
|
@test fields[1] === Displacement{3}
|
|||
|
|
|
|||
|
|
# Test required_state_variables (stateless)
|
|||
|
|
state_vars = required_state_variables(mat)
|
|||
|
|
@test state_vars isa Tuple
|
|||
|
|
@test length(state_vars) == 0
|
|||
|
|
@test isempty(state_vars)
|
|||
|
|
|
|||
|
|
# Test helper functions
|
|||
|
|
@test is_stateful(mat) == false
|
|||
|
|
|
|||
|
|
state_types = get_state_variable_types(mat)
|
|||
|
|
@test state_types isa Tuple
|
|||
|
|
@test length(state_types) == 0
|
|||
|
|
|
|||
|
|
state_symbols = get_state_variable_symbols(mat)
|
|||
|
|
@test state_symbols isa Tuple
|
|||
|
|
@test length(state_symbols) == 0
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
@testset "Trait function existence" begin
|
|||
|
|
# Test that trait functions are exported and callable
|
|||
|
|
@test isdefined(JuliaFEM, :supported_physics)
|
|||
|
|
@test isdefined(JuliaFEM, :required_field_types)
|
|||
|
|
@test isdefined(JuliaFEM, :required_state_variables)
|
|||
|
|
@test isdefined(JuliaFEM, :get_state_variable_types)
|
|||
|
|
@test isdefined(JuliaFEM, :get_state_variable_symbols)
|
|||
|
|
@test isdefined(JuliaFEM, :is_stateful)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
@testset "Helper function consistency" begin
|
|||
|
|
mat = LinearElastic(E=210e9, ν=0.3)
|
|||
|
|
|
|||
|
|
# For stateless material
|
|||
|
|
@test is_stateful(mat) == false
|
|||
|
|
@test isempty(required_state_variables(mat))
|
|||
|
|
@test isempty(get_state_variable_types(mat))
|
|||
|
|
@test isempty(get_state_variable_symbols(mat))
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
@testset "Compositional design verification" begin
|
|||
|
|
# This test verifies the compositional design philosophy:
|
|||
|
|
# Materials declare tuples of state variable types,
|
|||
|
|
# and each state variable has its own traits
|
|||
|
|
|
|||
|
|
mat = LinearElastic(E=210e9, ν=0.3)
|
|||
|
|
|
|||
|
|
# LinearElastic should have no state variables
|
|||
|
|
vars = required_state_variables(mat)
|
|||
|
|
@test vars === ()
|
|||
|
|
|
|||
|
|
# If a material HAD state variables (e.g., PerfectPlasticity),
|
|||
|
|
# we could query each variable's traits like this:
|
|||
|
|
# vars = required_state_variables(material)
|
|||
|
|
# for var in vars
|
|||
|
|
# concrete_type = state_variable_type(var)
|
|||
|
|
# symbol = default_symbol(var)
|
|||
|
|
# end
|
|||
|
|
|
|||
|
|
# The key insight: state variables are building blocks,
|
|||
|
|
# materials compose them to declare requirements
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
@testset "Physics to field type derivation" begin
|
|||
|
|
mat = LinearElastic(E=210e9, ν=0.3)
|
|||
|
|
|
|||
|
|
# Test that required_field_types correctly derives from supported_physics
|
|||
|
|
physics = supported_physics(mat)
|
|||
|
|
fields = required_field_types(mat)
|
|||
|
|
|
|||
|
|
@test length(physics) == length(fields)
|
|||
|
|
|
|||
|
|
for (p, f) in zip(physics, fields)
|
|||
|
|
# Each physics should map to its required field
|
|||
|
|
@test f === required_field_type(p)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|