mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-08-31 08:16:23 +00:00
240 lines
8.1 KiB
Julia
240 lines
8.1 KiB
Julia
# This file is a part of JuliaFEM.
|
|
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
|
|
|
include("vonmises.jl")
|
|
|
|
# Elasticity problems
|
|
abstract ElasticPlasticProblem <: AbstractProblem
|
|
abstract PlaneStressElasticPlasticProblem <: ElasticPlasticProblem
|
|
|
|
function get_unknown_field_name{P<:ElasticPlasticProblem}(::Type{P})
|
|
return "displacement"
|
|
end
|
|
|
|
function get_unknown_field_type{P<:ElasticPlasticProblem}(::Type{P})
|
|
return Vector{Float64}
|
|
end
|
|
|
|
# 3D Elasticity problems
|
|
function ElasticPlasticProblem(dim::Int=3, elements=[])
|
|
return Problem{ElasticPlasticProblem}("elasticplastic problem", dim, elements)
|
|
end
|
|
|
|
# 2D Plane stress elasticity problems
|
|
function PlaneStressElasticPlasticProblem(dim::Int=2, elements=[])
|
|
return Problem{PlaneStressElasticPlasticProblem}("plane stress elasticplastic problem", dim, elements)
|
|
end
|
|
|
|
|
|
function get_residual_vector{P<:PlaneStressElasticPlasticProblem}(problem::Problem{P}, element::Element, ip::IntegrationPoint, time::Number; variation=nothing)
|
|
r = zeros(Float64, problem.dim, length(element))
|
|
|
|
J = get_jacobian(element, ip, time)
|
|
|
|
# internal forces
|
|
if haskey(element, "youngs modulus") && haskey(element, "poissons ratio")
|
|
if !haskey(element, "integration points")
|
|
if P == PlaneStressElasticPlasticProblem
|
|
last_stress = zeros(2,2)
|
|
last_strain = zeros(2,2)
|
|
else
|
|
last_stress = zeros(3,3)
|
|
last_strain = zeros(3,3)
|
|
end
|
|
else
|
|
for each_ip in element("integration points", time)
|
|
if isapprox(each_ip.xi, ip.xi)
|
|
last_stress = ip("stress", time)
|
|
last_strain = ip("stress", time)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
u = element("displacement", time, variation)
|
|
grad = element(ip, time, Val{:grad})
|
|
gradu = grad*u
|
|
|
|
# deformation gradient
|
|
F = I + gradu
|
|
E = 1/2*(F'*F - I)
|
|
|
|
#E = 1/2*(gradu + gradu') # finite strain (total)
|
|
|
|
# material
|
|
young = element("youngs modulus", ip, time)
|
|
poisson = element("poissons ratio", ip, time)
|
|
stress_y = element("yield stress", time).data
|
|
dstrain = E - last_strain
|
|
de_v = [dstrain[1,1], dstrain[2,2], dstrain[1,2]]
|
|
material_model = element("material model", time)
|
|
s = last_stress
|
|
de = copy(ForwardDiff.get_value(dstrain))
|
|
|
|
if P == PlaneStressElasticPlasticProblem
|
|
C = stiffnessTensorPlaneStress(young, poisson)
|
|
s_v = [s[1,1], s[2,2], s[1,2]]
|
|
de_ = [de[1,1], de[2,2], de[1,2]]
|
|
problem_stress_type = :PlaneStressElasticPlasticProblem
|
|
else
|
|
C = stiffnessTensor(young, poisson)
|
|
s_v = [s[1,1], s[2,2], s[3,3], s[2,3], s[1,3], s[1,2]]
|
|
de_ = [de[1,1], de[2,2], de[3,3], de[2,3], de[1,3], de[1,2]]
|
|
problem_stress_type = :ElasticPlasticProblem
|
|
end
|
|
dep = zeros(3)
|
|
stress_inc, dep = calculate_stress(de_,
|
|
s_v,
|
|
C,
|
|
stress_y,
|
|
Val{:vonMises},
|
|
Val{problem_stress_type})
|
|
info("%% ", dep)
|
|
s_v += C * (de_v - dep)
|
|
info("--: ", ForwardDiff.get_value(s_v))
|
|
# stress
|
|
if P == PlaneStressElasticPlasticProblem
|
|
S = [s_v[1] s_v[3];
|
|
s_v[3] s_v[2]]
|
|
else
|
|
S = [s_v[1] s_v[6] s_v[5];
|
|
s_v[6] s_v[2] s_v[4];
|
|
s_v[5] s_v[4] s_v[3]]
|
|
end
|
|
r += F*S*grad*det(J)
|
|
end
|
|
|
|
# external forces - volume load
|
|
if haskey(element, "displacement load")
|
|
basis = element(ip, time)
|
|
b = element("displacement load", ip, time)
|
|
r -= b*basis*det(J)
|
|
end
|
|
|
|
# external forces - surface traction force
|
|
if haskey(element, "displacement traction force")
|
|
basis = element(ip, time)
|
|
T = element("displacement traction force", ip, time)
|
|
JT = transpose(J)
|
|
s = size(JT, 2) == 1 ? JT : cross(JT[:,1], JT[:,2])
|
|
r -= T*basis*norm(s)
|
|
end
|
|
|
|
return vec(r)
|
|
end
|
|
|
|
|
|
|
|
#=
|
|
function get_residual_vector{P<:ElasticPlasticProblem}(problem::Problem{P}, element::Element, ip::IntegrationPoint, time::Number; variation=nothing)
|
|
r = zeros(Float64, problem.dim, length(element))
|
|
|
|
J = get_jacobian(element, ip, time)
|
|
|
|
info("_____________________")
|
|
# internal forces
|
|
if haskey(element, "youngs modulus") && haskey(element, "poissons ratio")
|
|
|
|
if !haskey(element, "integration points")
|
|
if P == PlaneStressElasticPlasticProblem
|
|
last_stress = zeros(2,2)
|
|
last_strain = zeros(2,2)
|
|
else
|
|
last_stress = zeros(3,3)
|
|
last_strain = zeros(3,3)
|
|
end
|
|
else
|
|
for each_ip in element("integration points", time)
|
|
if isapprox(each_ip.xi, ip.xi)
|
|
last_stress = ip("stress", time)
|
|
last_strain = ip("stress", time)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
u = element("displacement", time, variation)
|
|
grad = element(ip, time, Val{:grad})
|
|
gradu = grad*u
|
|
|
|
# deformation gradient
|
|
F = I + gradu
|
|
|
|
# material
|
|
young = element("youngs modulus", ip, time)
|
|
poisson = element("poissons ratio", ip, time)
|
|
mu = young/(2*(1+poisson))
|
|
lambda = young*poisson/((1+poisson)*(1-2*poisson))
|
|
if P == PlaneStressElasticityProblem
|
|
lambda = 2*lambda*mu/(lambda + 2*mu) # <- correction for 2d problems
|
|
end
|
|
|
|
# strain
|
|
E = 1/2*(F'*F - I)
|
|
#E = 1/2*(gradu + gradu') # finite strain (total)
|
|
|
|
young = element("youngs modulus", ip, time)
|
|
poisson = element("poissons ratio", ip, time)
|
|
stress_y = element("yield stress", time).data
|
|
dstrain = E - last_strain
|
|
material_model = element("material model", time)
|
|
s = last_stress
|
|
de = ForwardDiff.get_value(dstrain)
|
|
|
|
if P == PlaneStressElasticPlasticProblem
|
|
C = stiffnessTensorPlaneStress(young, poisson)
|
|
s_v = [s[1,1], s[2,2], s[1,2]]
|
|
de_ = [de[1,1], de[2,2], de[1,2]]
|
|
problem_stress_type = :PlaneStressElasticPlasticProblem
|
|
else
|
|
C = stiffnessTensor(young, poisson)
|
|
s_v = [s[1,1], s[2,2], s[3,3], s[2,3], s[1,3], s[1,2]]
|
|
de_ = [de[1,1], de[2,2], de[3,3], de[2,3], de[1,3], de[1,2]]
|
|
problem_stress_type = :ElasticPlasticProblem
|
|
end
|
|
|
|
stress_inc, lambda = plastic_multiplier = calculate_stress(de_,
|
|
s_v,
|
|
C,
|
|
stress_y,
|
|
Val{:vonMises},
|
|
Val{problem_stress_type})
|
|
|
|
# dep = lambda * dfds(s)
|
|
# upate_material_parameters!(...)
|
|
s_new = s_v + stress_inc
|
|
#S = [s_v[1] s_v[6] s_v[5];
|
|
# s_v[6] s_v[2] s_v[4];
|
|
# s_v[5] s_v[4] s_v[3]]
|
|
S = [s_new[1] s_new[3];
|
|
s_new[3] s_new[2]]
|
|
# S = C * (E - dep)
|
|
|
|
|
|
info("Stress: ", vec(ForwardDiff.get_value(S)))
|
|
# stress
|
|
#S = lambda*trace(E)*I + 2*mu*E
|
|
|
|
r += F*S*grad*det(J)
|
|
|
|
end
|
|
|
|
|
|
# external forces - volume load
|
|
if haskey(element, "displacement load")
|
|
basis = element(ip, time)
|
|
b = element("displacement load", ip, time)
|
|
r -= b*basis*det(J)
|
|
end
|
|
|
|
# external forces - surface traction force
|
|
if haskey(element, "displacement traction force")
|
|
basis = element(ip, time)
|
|
T = element("displacement traction force", ip, time)
|
|
JT = transpose(J)
|
|
s = size(JT, 2) == 1 ? JT : cross(JT[:,1], JT[:,2])
|
|
r -= T*basis*norm(s)
|
|
end
|
|
|
|
return vec(r)
|
|
end
|
|
=# #fff
|