2015-12-09 15:45:15 +02:00
|
|
|
|
using ForwardDiff
|
|
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
"""
|
|
|
|
|
|
Creating functions for newton: xₙ₊₁ = xₙ - df⁻¹ * f and initial values
|
|
|
|
|
|
"""
|
|
|
|
|
|
function find_root!(f, df, x; max_iter=50, norm_acc=1e-9)
|
2015-12-17 17:13:23 +02:00
|
|
|
|
converged = false
|
|
|
|
|
|
for i=1:max_iter
|
2016-10-02 17:34:05 +03:00
|
|
|
|
dx = -df(x) \ f(x)
|
|
|
|
|
|
x += dx
|
2016-10-03 08:47:20 +03:00
|
|
|
|
norm(dx) < norm_acc && (converged = true; break)
|
2015-12-17 17:13:23 +02:00
|
|
|
|
end
|
2016-10-02 18:43:34 +03:00
|
|
|
|
converged || error("No convergence in radial return!")
|
2016-10-02 17:34:05 +03:00
|
|
|
|
return x
|
2015-12-17 17:13:23 +02:00
|
|
|
|
end
|
2015-12-10 21:16:56 +02:00
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
"""
|
|
|
|
|
|
Equivalent tensile stress.
|
|
|
|
|
|
|
|
|
|
|
|
More info can be found from: https://en.wikipedia.org/wiki/Von_Mises_yield_criterion
|
|
|
|
|
|
Section: Reduced von Mises equation for different stress conditions
|
|
|
|
|
|
"""
|
|
|
|
|
|
function equivalent_stress(stress, ::Type{Val{:type_3d}})
|
|
|
|
|
|
stress_ten = [stress[1] stress[6] stress[5];
|
|
|
|
|
|
stress[6] stress[2] stress[4];
|
|
|
|
|
|
stress[5] stress[4] stress[3]]
|
|
|
|
|
|
stress_dev = stress_ten - 1/3 * trace(stress_ten) * eye(3)
|
|
|
|
|
|
s = vec(stress_dev)
|
|
|
|
|
|
return sqrt(3/2 * dot(s, s))
|
|
|
|
|
|
end
|
2015-12-12 15:22:31 +02:00
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
"""
|
|
|
|
|
|
http://www.efunda.com/formulae/solid_mechanics/mat_mechanics/hooke_plane_stress.cfm
|
2015-12-17 17:13:23 +02:00
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
von mises: plane stress
|
|
|
|
|
|
https://andriandriyana.files.wordpress.com/2008/03/yield_criteria.pdf
|
|
|
|
|
|
"""
|
|
|
|
|
|
function equivalent_stress(stress, ::Type{Val{:type_2d}})
|
2015-12-17 17:13:23 +02:00
|
|
|
|
s1, s2, t12 = stress
|
|
|
|
|
|
# Calculating principal stresses
|
|
|
|
|
|
# http://www.engineersedge.com/material_science/principal_vonmises_stress__13418.htm
|
|
|
|
|
|
se1 = (s1 + s2)/2 + sqrt(((s1 - s2)/2)^2 + t12^2)
|
|
|
|
|
|
se2 = (s1 + s2)/2 - sqrt(((s1 - s2)/2)^2 + t12^2)
|
2016-10-02 17:34:05 +03:00
|
|
|
|
|
2015-12-17 17:13:23 +02:00
|
|
|
|
return sqrt(se1^2 -se1*se2 + se2^2)
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
"""
|
|
|
|
|
|
https://andriandriyana.files.wordpress.com/2008/03/yield_criteria.pdf
|
|
|
|
|
|
"""
|
|
|
|
|
|
function yield_function(stress, stress_y, ::Type{Val{:von_mises}}, type_)
|
|
|
|
|
|
equivalent_stress(stress, type_) - stress_y
|
2015-12-17 17:13:23 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
function radial_return(params, dstrain, D, stress_y, stress_base, yield_surface_, type_)
|
2015-12-17 17:13:23 +02:00
|
|
|
|
|
|
|
|
|
|
# Creating wrapper for gradient
|
2016-10-03 08:47:20 +03:00
|
|
|
|
vm_wrap(stress_) = yield_function(stress_, stress_y, yield_surface_, type_)
|
2016-10-02 17:34:05 +03:00
|
|
|
|
dfds = x -> ForwardDiff.gradient(vm_wrap, x)
|
2015-12-17 17:13:23 +02:00
|
|
|
|
|
|
|
|
|
|
# Stress rate and total strain
|
2016-10-03 08:47:20 +03:00
|
|
|
|
dstress = params[1:end-1]
|
|
|
|
|
|
stress_tot = stress_base + dstress
|
2015-12-17 17:13:23 +02:00
|
|
|
|
|
|
|
|
|
|
# Calculating plastic strain rate
|
|
|
|
|
|
dstrain_p = params[end] * dfds(stress_tot)
|
|
|
|
|
|
|
|
|
|
|
|
# Calculating equations
|
2016-10-02 17:34:05 +03:00
|
|
|
|
function_1 = dstress - D * (dstrain - dstrain_p)
|
2015-12-17 17:13:23 +02:00
|
|
|
|
function_2 = vm_wrap(stress_tot)
|
|
|
|
|
|
[vec(function_1); function_2]
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2016-10-28 15:46:04 +03:00
|
|
|
|
function ideal_plasticity!(stress_new, stress_last, dstrain_vec, pstrain, D, params, Dtan, yield_surface_, time, dt, type_)
|
2015-12-17 17:13:23 +02:00
|
|
|
|
# Test stress
|
2016-10-02 17:34:05 +03:00
|
|
|
|
dstress = vec(D * dstrain_vec)
|
2016-10-03 08:47:20 +03:00
|
|
|
|
stress_trial = stress_last + dstress
|
2016-10-02 17:34:05 +03:00
|
|
|
|
stress_y = params["yield_stress"]
|
2015-12-17 17:13:23 +02:00
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
yield_curr = x -> yield_function(x, stress_y, yield_surface_, type_)
|
2016-10-02 18:43:34 +03:00
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
# Calculating and checking for yield
|
|
|
|
|
|
yield = yield_curr(stress_trial)
|
2015-12-17 17:13:23 +02:00
|
|
|
|
if isless(yield, 0.0)
|
2016-10-28 15:46:04 +03:00
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
stress_new[:] = stress_trial[:]
|
2016-10-02 17:34:05 +03:00
|
|
|
|
Dtan[:,:] = D[:,:]
|
2015-12-17 17:13:23 +02:00
|
|
|
|
else
|
2016-10-02 17:34:05 +03:00
|
|
|
|
# Creating functions for newton: xₙ₊₁ = xₙ - df⁻¹ \ f and initial values
|
2016-10-03 08:47:20 +03:00
|
|
|
|
f = stress_ -> radial_return(stress_, dstrain_vec, D, stress_y, stress_last, yield_surface_, type_)
|
2016-10-02 17:34:05 +03:00
|
|
|
|
df = x -> ForwardDiff.jacobian(f, x)
|
|
|
|
|
|
|
2016-10-03 08:47:20 +03:00
|
|
|
|
# Calculating root (two options)
|
|
|
|
|
|
vals = [vec(stress_trial - stress_last); 0.0]
|
|
|
|
|
|
|
|
|
|
|
|
#results = nlsolve(not_in_place(f), vals).zero
|
2016-10-02 18:43:34 +03:00
|
|
|
|
results = find_root!(f, df, vals)
|
2016-10-02 17:34:05 +03:00
|
|
|
|
|
2016-10-02 18:43:34 +03:00
|
|
|
|
# extracting results
|
2016-10-03 08:47:20 +03:00
|
|
|
|
dstress = results[1:end-1]
|
2015-12-17 17:13:23 +02:00
|
|
|
|
plastic_multiplier = results[end]
|
2016-10-02 18:43:34 +03:00
|
|
|
|
|
|
|
|
|
|
# Updating stress
|
|
|
|
|
|
stress_new[:] = stress_last + dstress
|
|
|
|
|
|
|
2016-10-28 15:46:04 +03:00
|
|
|
|
|
2016-10-02 18:43:34 +03:00
|
|
|
|
# Calculating plastic strain
|
2016-10-03 08:47:20 +03:00
|
|
|
|
dfds_ = x -> ForwardDiff.gradient(yield_curr, x)
|
2016-10-02 17:34:05 +03:00
|
|
|
|
dep = plastic_multiplier * dfds_(vec(stress_new))
|
|
|
|
|
|
|
2016-10-02 18:43:34 +03:00
|
|
|
|
# Equations for consistent tangent matrix can be found from:
|
|
|
|
|
|
# http://homes.civil.aau.dk/lda/continuum/plast.pdf
|
|
|
|
|
|
# equations: 152 & 153
|
2016-10-03 08:47:20 +03:00
|
|
|
|
D2g = x -> ForwardDiff.hessian(yield_curr, x)
|
2016-10-02 17:34:05 +03:00
|
|
|
|
Dc = (D^-1 + plastic_multiplier * D2g(stress_new))^-1
|
|
|
|
|
|
dfds = dfds_(stress_new)
|
2016-10-02 18:43:34 +03:00
|
|
|
|
Dtan[:,:] = Dc - (Dc * dfds * dfds' * Dc) / (dfds' * Dc * dfds)[1]
|
2016-10-28 15:46:04 +03:00
|
|
|
|
pstrain[:] = plastic_multiplier * dfds
|
2015-12-17 17:13:23 +02:00
|
|
|
|
end
|
|
|
|
|
|
end
|