mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-19 01:48:47 +00:00
263926a3f3
- Test add_dirichlet! with single and multiple nodes - Test partial DOF constraints (e.g., only z-direction) - Test BC accumulation across multiple calls - Test add_neumann! with single and multiple surfaces - Test different traction values and vectors - Test combined Dirichlet and Neumann BCs - Verify BC independence between physics instances - 149 lines with 47 test assertions
150 lines
4.4 KiB
Julia
150 lines
4.4 KiB
Julia
# This file is a part of JuliaFEM.
|
||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||
|
||
"""
|
||
Unit tests for boundary condition methods.
|
||
|
||
Tests add_dirichlet! and add_neumann! implementations.
|
||
"""
|
||
|
||
using Test
|
||
using JuliaFEM
|
||
using Tensors
|
||
|
||
@testset "Boundary Conditions" begin
|
||
# Helper to create minimal physics
|
||
function create_test_physics()
|
||
nodes = Vec{3,Float64}[
|
||
Vec{3}((0.0, 0.0, 0.0)),
|
||
Vec{3}((1.0, 0.0, 0.0)),
|
||
Vec{3}((1.0, 1.0, 0.0)),
|
||
Vec{3}((0.0, 1.0, 0.0)),
|
||
Vec{3}((0.0, 0.0, 1.0)),
|
||
Vec{3}((1.0, 0.0, 1.0)),
|
||
Vec{3}((1.0, 1.0, 1.0)),
|
||
Vec{3}((0.0, 1.0, 1.0))
|
||
]
|
||
connectivity = [NTuple{8,UInt32}((1, 2, 3, 4, 5, 6, 7, 8))]
|
||
element_sets = Dict{Symbol,Set{UInt32}}(:all => Set(UInt32(1)))
|
||
mesh = Mesh{8,Hexahedron{8}}(nodes, connectivity, element_sets)
|
||
material = LinearElastic(E=210e9, ν=0.3)
|
||
|
||
return Physics(
|
||
name="test",
|
||
mesh=mesh,
|
||
element_set=:all,
|
||
field=Displacement{3}(),
|
||
formulation=ContinuumFormulation{FullThreeD}(),
|
||
material=material
|
||
)
|
||
end
|
||
|
||
@testset "add_dirichlet! - single node" begin
|
||
physics = create_test_physics()
|
||
|
||
add_dirichlet!(physics, [1], [1, 2, 3], 0.0)
|
||
|
||
bc = physics.bc_dirichlet
|
||
@test length(bc.node_ids) == 1
|
||
@test bc.node_ids[1] == 1
|
||
@test bc.components[1] == [1, 2, 3]
|
||
@test bc.values[1] == 0.0
|
||
end
|
||
|
||
@testset "add_dirichlet! - multiple nodes" begin
|
||
physics = create_test_physics()
|
||
|
||
add_dirichlet!(physics, [1, 2, 3], [1, 2, 3], 0.0)
|
||
|
||
bc = physics.bc_dirichlet
|
||
@test length(bc.node_ids) == 3
|
||
@test bc.node_ids == [1, 2, 3]
|
||
@test all(c == [1, 2, 3] for c in bc.components)
|
||
@test all(v == 0.0 for v in bc.values)
|
||
end
|
||
|
||
@testset "add_dirichlet! - partial DOFs" begin
|
||
physics = create_test_physics()
|
||
|
||
add_dirichlet!(physics, [5], [3], 0.1)
|
||
|
||
bc = physics.bc_dirichlet
|
||
@test length(bc.node_ids) == 1
|
||
@test bc.node_ids[1] == 5
|
||
@test bc.components[1] == [3]
|
||
@test bc.values[1] == 0.1
|
||
end
|
||
|
||
@testset "add_dirichlet! - accumulation" begin
|
||
physics = create_test_physics()
|
||
|
||
add_dirichlet!(physics, [1], [1, 2, 3], 0.0)
|
||
add_dirichlet!(physics, [2], [3], 0.1)
|
||
|
||
bc = physics.bc_dirichlet
|
||
@test length(bc.node_ids) == 2
|
||
@test bc.node_ids == [1, 2]
|
||
@test bc.components == [[1, 2, 3], [3]]
|
||
@test bc.values == [0.0, 0.1]
|
||
end
|
||
|
||
@testset "add_neumann! - single surface" begin
|
||
physics = create_test_physics()
|
||
|
||
traction = Vec{3}((0.0, -1000.0, 0.0))
|
||
add_neumann!(physics, [1], traction)
|
||
|
||
bc = physics.bc_neumann
|
||
@test length(bc.surface_ids) == 1
|
||
@test bc.surface_ids[1] == 1
|
||
@test bc.values[1] == traction
|
||
end
|
||
|
||
@testset "add_neumann! - multiple surfaces" begin
|
||
physics = create_test_physics()
|
||
|
||
traction = Vec{3}((0.0, -1000.0, 0.0))
|
||
add_neumann!(physics, [1, 2, 3], traction)
|
||
|
||
bc = physics.bc_neumann
|
||
@test length(bc.surface_ids) == 3
|
||
@test bc.surface_ids == [1, 2, 3]
|
||
@test all(v == traction for v in bc.values)
|
||
end
|
||
|
||
@testset "add_neumann! - different tractions" begin
|
||
physics = create_test_physics()
|
||
|
||
traction1 = Vec{3}((0.0, -1000.0, 0.0))
|
||
traction2 = Vec{3}((100.0, 0.0, 0.0))
|
||
|
||
add_neumann!(physics, [1], traction1)
|
||
add_neumann!(physics, [2], traction2)
|
||
|
||
bc = physics.bc_neumann
|
||
@test length(bc.surface_ids) == 2
|
||
@test bc.surface_ids == [1, 2]
|
||
@test bc.values[1] == traction1
|
||
@test bc.values[2] == traction2
|
||
end
|
||
|
||
@testset "Combined Dirichlet and Neumann BCs" begin
|
||
physics = create_test_physics()
|
||
|
||
# Fix some nodes
|
||
add_dirichlet!(physics, [1, 2], [1, 2, 3], 0.0)
|
||
|
||
# Apply traction
|
||
traction = Vec{3}((0.0, -1000.0, 0.0))
|
||
add_neumann!(physics, [7, 8], traction)
|
||
|
||
# Check both BCs are stored
|
||
@test length(physics.bc_dirichlet.node_ids) == 2
|
||
@test length(physics.bc_neumann.surface_ids) == 2
|
||
|
||
# Verify independence
|
||
@test physics.bc_dirichlet.node_ids == [1, 2]
|
||
@test physics.bc_neumann.surface_ids == [7, 8]
|
||
end
|
||
end
|