fixed problems with surface loads. det(element, ip, time) should be avoided.

This commit is contained in:
Jukka Aho
2015-12-13 13:47:45 +02:00
parent 3242241cd4
commit ccf32d5b76
10 changed files with 102 additions and 63 deletions
+15 -14
View File
@@ -70,20 +70,20 @@ https://en.wikipedia.org/wiki/Hooke's_law
"""
function get_residual_vector{P<:ElasticityProblem}(problem::Problem{P}, element::Element, ip::IntegrationPoint, time::Number; variation=nothing)
# u = element("displacement", ip, time, variation)
r = zeros(Float64, problem.dim, length(element))
J = get_jacobian(element, ip, time)
# internal forces
if haskey(element, "youngs modulus") && haskey(element, "poissons ratio")
u = element("displacement", time, variation)
grad = element(ip, time, Val{:grad})
gradu = grad*u
F = I + gradu # deformation gradient
# info("gradu = \n$(ForwardDiff.get_value(gradu))")
# deformation gradient
F = I + gradu
# material
young = element("youngs modulus", ip, time)
poisson = element("poissons ratio", ip, time)
mu = young/(2*(1+poisson))
@@ -91,29 +91,30 @@ function get_residual_vector{P<:ElasticityProblem}(problem::Problem{P}, element:
if P == PlaneStressElasticityProblem
lambda = 2*lambda*mu/(lambda + 2*mu) # <- correction for 2d problems
end
E = 1/2*(F'*F - I) # strain
# strain
E = 1/2*(F'*F - I)
# stress
S = lambda*trace(E)*I + 2*mu*E
#J = det(element, ip, time)
#T = J^-1*F*S*F'
#ip["cauchy stress"] = T
#ip["gl strain"] = E
r += F*S*grad
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
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)
r -= T*basis
JT = transpose(J)
s = size(JT, 2) == 1 ? JT : cross(JT[:,1], JT[:,2])
r -= T*basis*norm(s)
end
return vec(r)
+26 -4
View File
@@ -197,13 +197,35 @@ function call(element::Element, field_name::ASCIIString)
return element[field_name]
end
function LinAlg.det{E<:AbstractElement}(element::Element{E}, ip::IntegrationPoint, time::Number=0.0)
""" Return the jacobian of element. """
function get_jacobian{E}(element::Element{E}, xi::Vector{Float64}, time::Real)
X = element("geometry", time)
dN = get_dbasis(E, ip.xi)
dN = get_dbasis(E, xi)
J = sum([kron(dN[:,i], X[i]') for i=1:length(X)])
m, n = size(J)
return m == n ? det(J) : norm(J)
return J
end
function get_jacobian{E}(element::Element{E}, ip::IntegrationPoint, time::Real)
return get_jacobian(element, ip.xi, time)
end
""" Return the determinant of jacobian. """
function LinAlg.det{E<:AbstractElement}(element::Element{E}, xi::Vector{Float64}, time::Real)
warn("det(element, ip, time) is ambiguous: use J = get_jacobian(element, ip, time); det(J) instead.")
J = get_jacobian(element, xi, time)
n, m = size(J)
if n == m
return det(J)
end
JT = transpose(J)
s = size(JT, 2) == 1 ? norm(JT) : norm(cross(JT[:,1], JT[:,2]))
return s
end
function LinAlg.det{E<:AbstractElement}(element::Element{E}, ip::IntegrationPoint, time::Real)
return det(element, ip.xi, time)
end
""" Check does field exist. """
function Base.haskey(element::Element, what)
+7 -9
View File
@@ -77,15 +77,15 @@ function assemble!(assembly::Assembly, problem::Problem, element::Element, time:
# 1. if equations are defined we just integrate them, without caring how they are done
if has_mass_matrix(problem, element) || has_stiffness_matrix(problem, element) || has_force_vector(problem, element)
for ip in get_integration_points(element)
s = ip.weight*det(element, ip, time)
w = ip.weight*det(J)
if has_mass_matrix(element)
add!(assembly.mass_matrix, gdofs, gdofs, s*get_mass_matrix(problem, element, ip, time))
add!(assembly.mass_matrix, gdofs, gdofs, w*get_mass_matrix(problem, element, ip, time))
end
if has_stiffness_matrix(element)
add!(assembly.stiffness_matrix, gdofs, gdofs, s*get_stiffness_matrix(problem, element, ip, time))
add!(assembly.stiffness_matrix, gdofs, gdofs, w*get_stiffness_matrix(problem, element, ip, time))
end
if has_force_vector(element)
add!(assembly.force_vector, gdofs, s*get_force_vector(problem, element, ip, time))
add!(assembly.force_vector, gdofs, w*get_force_vector(problem, element, ip, time))
end
end
# external loads -- if any nodal loads is defined add to force vector
@@ -104,16 +104,15 @@ function assemble!(assembly::Assembly, problem::Problem, element::Element, time:
df = similar(field, data)
# integrate potential energy
for ip in get_integration_points(element)
s = ip.weight*det(element, ip, time)
dw = get_potential_energy(problem, element, ip, time; variation=df)
W += s*dw
W += ip.weight*dw
end
# external energy -- if any nodal loads is defined, decrease from potential energy
if haskey(element, "$unknown_field_name nodal load")
P = element["$unknown_field_name nodal load"](time)
W -= dot(vec(P), vec(df))
end
return isa(W, Array) ? W[1] : W
return W[1]
end
hessian, allresults = ForwardDiff.hessian(calc_W, vec(field), AllResults, cache=autodiffcache)
@@ -133,9 +132,8 @@ function assemble!(assembly::Assembly, problem::Problem, element::Element, time:
gauss_fields = IntegrationPoint[]
# integrate residual vector
for ip in get_integration_points(element)
s = ip.weight*det(element, ip, time)
dr = get_residual_vector(problem, element, ip, time; variation=df)
R += s*dr
R += ip.weight*dr
if ip.changed
push!(gauss_fields, ip)
end
+6 -5
View File
@@ -46,24 +46,25 @@ function assemble!(assembly::Assembly, problem::Problem{HeatProblem}, element::E
gdofs = get_gdofs(element, problem.dim)
for ip in get_integration_points(element)
w = ip.weight*det(element, ip, time)
w = ip.weight
J = get_jacobian(element, ip, time)
N = element(ip, time)
if haskey(element, "density")
rho = element("density", ip, time)
add!(assembly.mass_matrix, gdofs, gdofs, w*rho*N'*N)
add!(assembly.mass_matrix, gdofs, gdofs, w*rho*N'*N*det(J))
end
if haskey(element, "temperature thermal conductivity")
dN = element(ip, time, Val{:grad})
k = element("temperature thermal conductivity", ip, time)
add!(assembly.stiffness_matrix, gdofs, gdofs, w*k*dN'*dN)
add!(assembly.stiffness_matrix, gdofs, gdofs, w*k*dN'*dN*det(J))
end
if haskey(element, "temperature load")
f = element("temperature load", ip, time)
add!(assembly.force_vector, gdofs, w*N'*f)
add!(assembly.force_vector, gdofs, w*N'*f*det(J))
end
if haskey(element, "temperature flux")
g = element("temperature flux", ip, time)
add!(assembly.force_vector, gdofs, w*N'*g)
add!(assembly.force_vector, gdofs, w*N'*g*norm(J))
end
end
end
+12 -10
View File
@@ -16,7 +16,8 @@ function assemble!{E<:CG, P<:LinearElasticityProblem}(assembly::Assembly, proble
ndim, nnodes = size(E)
B = zeros(6, 3*nnodes)
for ip in get_integration_points(element)
w = ip.weight*det(element, ip, time)
w = ip.weight
J = get_jacobian(element, ip, time)
N = element(ip, time)
if haskey(element, "youngs modulus") && haskey(element, "poissons ratio")
v = element("poissons ratio", ip, time)
@@ -44,16 +45,16 @@ function assemble!{E<:CG, P<:LinearElasticityProblem}(assembly::Assembly, proble
B[6, 3*(i-1)+1] = dN[3,i]
B[6, 3*(i-1)+3] = dN[1,i]
end
add!(assembly.stiffness_matrix, gdofs, gdofs, w*B'*C*B)
add!(assembly.stiffness_matrix, gdofs, gdofs, w*B'*C*B*det(J))
end
if haskey(element, "displacement load")
b = element("displacement load", ip, time)
add!(assembly.force_vector, gdofs, w*N'*b)
add!(assembly.force_vector, gdofs, w*N'*b*det(J))
end
if haskey(element, "displacement traction force")
T = element("displacement traction force", ip, time)
L = w*T*N
# dump(L)
JT = transpose(J)
L = w*T*N*norm(cross(JT[:,1], JT[:,2]))
add!(assembly.force_vector, gdofs, vec(L))
end
end
@@ -72,7 +73,8 @@ function assemble!{E<:CG, P<:PlaneStressLinearElasticityProblem}(assembly::Assem
ndim, nnodes = size(E)
B = zeros(3, 2*nnodes)
for ip in get_integration_points(element)
w = ip.weight*det(element, ip, time)
w = ip.weight
J = get_jacobian(element, ip, time)
N = element(ip, time)
if haskey(element, "youngs modulus") && haskey(element, "poissons ratio")
nu = element("poissons ratio", ip, time)
@@ -89,17 +91,17 @@ function assemble!{E<:CG, P<:PlaneStressLinearElasticityProblem}(assembly::Assem
B[3, 2*(i-1)+1] = dN[2,i]
B[3, 2*(i-1)+2] = dN[1,i]
end
add!(assembly.stiffness_matrix, gdofs, gdofs, w*B'*C*B)
add!(assembly.stiffness_matrix, gdofs, gdofs, w*B'*C*B*det(J))
end
if haskey(element, "displacement load")
b = element("displacement load", ip, time)
add!(assembly.force_vector, gdofs, w*N'*b)
add!(assembly.force_vector, gdofs, w*N'*b*det(J))
end
if haskey(element, "displacement traction force")
T = element("displacement traction force", ip, time)
L = w*T*N
# dump(L)
L = w*T*N*norm(J)
add!(assembly.force_vector, gdofs, vec(L))
end
end
end