Skip to content

Commit e65ec8b

Browse files
authored
Add support for finite strain material models (#59)
* Add support for finite strain material models * Add tests * Add Newton as specific test-dependency with sources
1 parent d25b75c commit e65ec8b

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

Project.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@ julia = "1.11"
2020
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
2121
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
2222
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
23+
MechanicalMaterialModels = "b3282f9b-607f-4337-ab95-e5488ab5652c"
24+
Newton = "83aa5b51-0588-403c-85e4-434ec185aae7"
2325

2426
[targets]
25-
test = ["Test", "Logging", "SparseArrays"]
27+
test = ["Test", "Logging", "SparseArrays", "MechanicalMaterialModels", "Newton"]
2628

2729
[sources]
2830
MaterialModelsBase = {url = "https://github.com/KnutAM/MaterialModelsBase.jl.git"}
31+
MechanicalMaterialModels = {url = "https://github.com/KnutAM/MechanicalMaterialModels.jl.git"}
32+
Newton = {url = "https://github.com/KnutAM/Newton.jl.git"}

src/Utils/MaterialModelsBase.jl

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ where ``\\sigma`` is calculated with the `material_response` function from
1616
Note that `create_cell_state` is already implemented for `<:AbstractMaterial`.
1717
"""
1818
function FerriteAssembly.element_routine!(
19+
Ke, re, state::Vector{<:MMB.AbstractMaterialState},
20+
ae, material::MMB.AbstractMaterial, cellvalues::AbstractCellValues, buffer)
21+
return mechanical_element_routine!(MMB.get_tensorbase(material), Ke, re, state, ae, material, cellvalues, buffer)
22+
end
23+
24+
function mechanical_element_routine!(::Type{<:SymmetricTensor{2}},
1925
Ke, re, state::Vector{<:MMB.AbstractMaterialState},
2026
ae, material::MMB.AbstractMaterial, cellvalues::AbstractCellValues, buffer)
2127
cache = FerriteAssembly.get_user_cache(buffer)
@@ -40,6 +46,31 @@ function FerriteAssembly.element_routine!(
4046
end
4147
end
4248

49+
function mechanical_element_routine!(::Type{<:Tensor{2}},
50+
Ke, re, state::Vector{<:MMB.AbstractMaterialState},
51+
ae, material::MMB.AbstractMaterial, cellvalues::AbstractCellValues, buffer)
52+
cache = FerriteAssembly.get_user_cache(buffer)
53+
Δt = FerriteAssembly.get_time_increment(buffer)
54+
state_old = FerriteAssembly.get_old_state(buffer)
55+
n_basefuncs = getnbasefunctions(cellvalues)
56+
for q_point in 1:getnquadpoints(cellvalues)
57+
# For each integration point, compute stress and material stiffness
58+
H = function_gradient(cellvalues, q_point, ae) # Displacement gradient
59+
F = H + one(H) # Deformation gradient
60+
P, D, state[q_point] = MMB.material_response(material, F, state_old[q_point], Δt, cache)
61+
= getdetJdV(cellvalues, q_point)
62+
for i in 1:n_basefuncs
63+
∇δN = shape_gradient(cellvalues, q_point, i)
64+
re[i] += (∇δN P) *# add internal force to residual
65+
∇δN_D = ∇δN D # temporary value for speed
66+
for j in 1:n_basefuncs
67+
∇N = shape_gradient(cellvalues, q_point, j)
68+
Ke[i, j] += (∇δN_D ∇N) *
69+
end
70+
end
71+
end
72+
end
73+
4374
"""
4475
FerriteAssembly.element_residual!(
4576
re, state::Vector{<:MMB.AbstractMaterialState}, ae,
@@ -49,6 +80,12 @@ The `element_residual!` implementation corresponding to the `element_routine!` i
4980
for a `MaterialModelsBase.AbstractMaterial`
5081
"""
5182
function FerriteAssembly.element_residual!(
83+
re, state::Vector{<:MMB.AbstractMaterialState},
84+
ae, material::MMB.AbstractMaterial, cellvalues::AbstractCellValues, buffer)
85+
return mechanical_element_residual!(MMB.get_tensorbase(material), re, state, ae, material, cellvalues, buffer)
86+
end
87+
88+
function mechanical_element_residual!(::Type{<:SymmetricTensor{2}},
5289
re, state::Vector{<:MMB.AbstractMaterialState},
5390
ae, material::MMB.AbstractMaterial, cellvalues::AbstractCellValues, buffer)
5491
cache = FerriteAssembly.get_user_cache(buffer)
@@ -67,6 +104,26 @@ function FerriteAssembly.element_residual!(
67104
end
68105
end
69106

107+
function mechanical_element_residual!(::Type{<:Tensor{2}},
108+
re, state::Vector{<:MMB.AbstractMaterialState},
109+
ae, material::MMB.AbstractMaterial, cellvalues::AbstractCellValues, buffer)
110+
cache = FerriteAssembly.get_user_cache(buffer)
111+
Δt = FerriteAssembly.get_time_increment(buffer)
112+
state_old = FerriteAssembly.get_old_state(buffer)
113+
n_basefuncs = getnbasefunctions(cellvalues)
114+
for q_point in 1:getnquadpoints(cellvalues)
115+
# For each integration point, compute stress and material stiffness
116+
H = function_gradient(cellvalues, q_point, ae) # Displacement gradient
117+
F = H + one(H) # Deformation gradient
118+
P, _, state[q_point] = MMB.material_response(material, F, state_old[q_point], Δt, cache)
119+
= getdetJdV(cellvalues, q_point)
120+
for i in 1:n_basefuncs
121+
∇δN = shape_gradient(cellvalues, q_point, i)
122+
re[i] += (∇δN P) *# add internal force to residual
123+
end
124+
end
125+
end
126+
70127
"""
71128
FerriteAssembly.create_cell_state(m::MMB.AbstractMaterial, cv::AbstractCellValues, args...)
72129

test/example_elements.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,25 @@ end
7373
test_equality(m, weak, Val(true))
7474
test_equality(m, mmb, Val(true))
7575
end
76+
@testset "Hyperelasticity" begin
77+
G, K = (1 + rand(), 1 + rand())
78+
m_3d = MMM.CompressibleNeoHooke(; G, K)
79+
m = MMB.ReducedStressState(MMB.PlaneStrain(), m_3d)
80+
function weakform_neohooke(δu, ∇δu::Tensor{2,2}, u, ∇u::Tensor{2,2}, u_dot, ∇u_dot)
81+
# 2D, consider as plane strain]
82+
make3d(t::Tensor{2,2,T}) where {T} = Tensor{2,3,T}((i,j) -> i 2 && j 2 ? t[i,j] : zero(T))
83+
return weakform_neohooke(δu, make3d(∇δu), u, make3d(∇u), u_dot, ∇u_dot)
84+
end
85+
function weakform_neohooke(δu, ∇δu::Tensor{2,3}, u, ∇u::Tensor{2,3}, u_dot, ∇u_dot)
86+
F = one(∇u) + ∇u
87+
C = tdot(F)
88+
S = MMM.compute_stress(m_3d, C)
89+
P = F S
90+
return ∇δu P
91+
end
92+
weak = EE.WeakForm(weakform_neohooke)
93+
test_equality(m, weak, Val(true))
94+
end
7695
@testset "J2Plasticity" begin
7796
E = 1.0 + rand()
7897
H = 0.1 + 0.9*rand()

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ using Test
55
import FerriteAssembly as FA
66
import FerriteAssembly.ExampleElements as EE
77
import MaterialModelsBase as MMB
8+
import MechanicalMaterialModels as MMM
89
using Logging
910

1011
include("replacements.jl")

0 commit comments

Comments
 (0)