define "local" coordinate system for elements

This commit is contained in:
Jukka Aho
2015-12-20 21:17:47 +02:00
parent c73bf3c42b
commit 2e3feb4e6f
6 changed files with 3038 additions and 29 deletions
File diff suppressed because one or more lines are too long
+4 -3
View File
@@ -141,9 +141,10 @@ end
""" Call solver to solve a set of problems. """
function call(solver::DirectSolver, time::Number=0.0)
info("Starting solver $(solver.name)")
info("# of field problems: $(length(solver.field_problems))")
info("# of boundary problems: $(length(solver.boundary_problems))")
(length(solver.field_problems) != 0) || error("no field problems defined.")
(length(solver.field_problems) != 0) || error("no field problems defined for solver, use push!(solver, problem, ...) to define field problems.")
timing = Dict{ASCIIString, Float64}()
tic(timing, "solver")
@@ -202,7 +203,7 @@ function call(solver::DirectSolver, time::Number=0.0)
info("Assembling field problems...")
field_assembly = Assembly()
for (i, problem) in enumerate(solver.field_problems)
info("Assembling body $i...")
info("Assembling body $i: $(problem.name)")
append!(field_assembly, assemble(problem, time))
end
K = sparse(field_assembly.stiffness_matrix)
@@ -217,7 +218,7 @@ function call(solver::DirectSolver, time::Number=0.0)
info("Assembling boundary problems...")
boundary_assembly = Assembly()
for (i, problem) in enumerate(solver.boundary_problems)
info("Assembling boundary $i...")
info("Assembling boundary $i: $(problem.name)")
append!(boundary_assembly, assemble(problem, time))
end
C = sparse(boundary_assembly.stiffness_matrix, dim, dim)
+34 -20
View File
@@ -243,34 +243,48 @@ end
""" Calculate local normal-tangential coordinates for element. """
function calculate_normal_tangential_coordinates!{E}(element::Element{E}, time::Real)
proj(u, v) = dot(v, u) / dot(u, u) * u
ntcoords = Matrix[]
refcoords = get_reference_element_coordinates(E)
x = element("geometry", time)
for xi in refcoords
dN = get_dbasis(E, xi)*x
normal = cross(dN[:,1], dN[:,2])
normal /= norm(normal)
u1 = normal
j = indmax(abs(u1))
v2 = zeros(3)
v2[mod(j,3)+1] = 1.0
u2 = v2 - proj(u1, v2)
u3 = cross(u1, u2)
tangent1 = u2/norm(u2)
tangent2 = u3/norm(u3)
push!(ntcoords, [normal tangent1 tangent2])
n, m = size(dN)
@assert n != m # if n == m -> this is not manifold
if m == 1 # plane case
tangent = dN / norm(dN)
normal = [-tangent[2] tangent[1]]'
push!(ntcoords, [normal tangent])
elseif m == 2
normal = cross(dN[:,1], dN[:,2])
normal /= norm(normal)
u1 = normal
j = indmax(abs(u1))
v2 = zeros(3)
v2[mod(j,3)+1] = 1.0
u2 = v2 - dot(u1, v2) / dot(v2, v2) * v2
u3 = cross(u1, u2)
tangent1 = u2/norm(u2)
tangent2 = u3/norm(u3)
push!(ntcoords, [normal tangent1 tangent2])
else
error("calculate_normal_tangential_coordinates!(): n=$n, m=$m")
end
end
element["normal-tangential coordinates"] = ntcoords
end
""" Pick values from nodes and set to element according to connectivity. """
function update(element::Element, field_name::ASCIIString, data::Union{Vector, Dict})
element[field_name] = [data[i] for i in get_connectivity(element)]
end
function update(elements::Vector{Element}, field_name::ASCIIString, data::Union{Vector, Dict})
# info("update $field_name for $(length(elements)) elements.")
function calculate_normal_tangential_coordinates!{E}(elements::Vector{Element{E}}, time::Real)
for element in elements
update(element, field_name, data)
calculate_normal_tangential_coordinates!(element, time)
end
end
""" Pick values from nodes and set to element according to connectivity. """
function update!(element::Element, field_name::ASCIIString, data::Union{Vector, Dict})
element[field_name] = [data[i] for i in get_connectivity(element)]
end
function update!(elements::Vector{Element}, field_name::ASCIIString, data::Union{Vector, Dict})
# info("update $field_name for $(length(elements)) elements.")
for element in elements
update!(element, field_name, data)
end
end
+6 -2
View File
@@ -180,8 +180,12 @@ for op = (:+, :*, :/, :-)
@eval ($op)(increment::Increment, field::DCTI) = ($op)(increment.data, field.data)
@eval ($op)(field::DCTI, increment::Increment) = ($op)(increment.data, field.data)
@eval ($op)(field1::DCTI, field2::DCTI) = ($op)(field1.data, field2.data)
@eval ($op)(field::DCTI, k) = ($op)(field.data, k)
@eval ($op)(k, field::DCTI) = ($op)(field.data, k)
@eval ($op)(field::DCTI, k::Number) = ($op)(field.data, k)
@eval ($op)(k::Number, field::DCTI) = ($op)(field.data, k)
end
function Base.(:+)(f1::DVTI, f2::DVTI)
return DVTI(f1.data + f2.data)
end
function Base.vec(field::DVTI)
+17
View File
@@ -118,6 +118,23 @@ function assemble!{E<:CG, P<:PlaneStressLinearElasticityProblem}(assembly::Assem
L = w*T*N*norm(J)
add!(assembly.force_vector, gdofs, vec(L))
end
for dim in 1:problem.dim
if haskey(element, "displacement traction force $dim")
T = element("displacement traction force $dim", ip, time)
ldofs = gdofs[dim:problem.dim:end]
L = w*T*N*norm(J)
add!(assembly.force_vector, ldofs, vec(L))
end
end
if haskey(element, "displacement traction force N")
# surface pressure
p = zeros(2)
p[1] = element("displacement traction force N", ip, time)
R = element("normal-tangential coordinates", ip, time)
T = R'*p
L = w*T*N*norm(J)
add!(assembly.force_vector, gdofs, vec(L))
end
end
end
+4 -4
View File
@@ -6,7 +6,7 @@ module MortarTests
using JuliaFEM.Test
using JuliaFEM.Core: Element, Seg2, Quad4, Tri3, Hex8, MortarProblem, Assembly, assemble!,
get_connectivity, update
get_connectivity, update!
using JuliaFEM.Core: PlaneStressElasticityProblem, DirichletProblem, DirectSolver
# 2d stuff
@@ -727,7 +727,7 @@ function test_3d_problem()
l2u = Quad4([5, 6, 7, 8])
u2l = Quad4([9, 10, 11, 12])
elements = Element[el1, el2, sym121, sym131, sym132, sym231, sym232, force, l2u, u2l]
update(elements, "geometry", nodes)
update!(elements, "geometry", nodes)
el1["youngs modulus"] = el2["youngs modulus"] = 900.0
el1["poissons ratio"] = el2["poissons ratio"] = 0.25
sym121["displacement 3"] = 0.0
@@ -859,8 +859,8 @@ end
mel7 = Quad4([18, 19, 23, 22])
mel8 = Quad4([19, 20, 24, 23])
mel9 = Quad4([20, 21, 25, 24])
update(Element[sel1, sel2, sel3, sel4, mel1, mel2, mel3,
mel4, mel5, mel6, mel7, mel8, mel9], "geometry", nodes)
update!(Element[sel1, sel2, sel3, sel4, mel1, mel2, mel3,
mel4, mel5, mel6, mel7, mel8, mel9], "geometry", nodes)
calculate_normal_tangential_coordinates!(sel1, 0.0)
calculate_normal_tangential_coordinates!(sel2, 0.0)
calculate_normal_tangential_coordinates!(sel3, 0.0)