Skip to content

Commit

Permalink
use FEMBase v0.1.x (#185)
Browse files Browse the repository at this point in the history
Lots of stuff moved from JuliaFEM.jl to FEMBase.jl.
  • Loading branch information
ahojukka5 authored Jan 19, 2018
1 parent 35307b1 commit d7bef41
Show file tree
Hide file tree
Showing 45 changed files with 232 additions and 1,246 deletions.
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
julia 0.6
FEMBase 0.0 0.1-
FEMBase 0.1 0.2-
ForwardDiff
LightXML 0.4
HDF5 0.7
Expand Down
15 changes: 1 addition & 14 deletions src/JuliaFEM.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,6 @@ This is JuliaFEM -- Finite Element Package
module JuliaFEM

using FEMBase
using FEMBase: SparseMatrixCOO, SparseVectorCOO, Node, BasisInfo,
Discrete, Variable, TimeVariant, TimeInvariant, Field,
DCTI, DVTI, DCTV, DVTV, CCTI, CVTI, CCTV, CVTV, Increment,
IP, AbstractProblem, IntegrationPoint
using FEMBase: is_field_problem, is_boundary_problem, get_elements,
get_connectivity, assemble_prehook!, assemble_posthook!,
get_parent_field_name, get_reference_coordinates,
get_assembly, get_nonzero_rows, get_nonzero_columns,
eval_basis!, get_basis, get_dbasis, grad!, get_dualbasis,
assemble_mass_matrix!, get_local_coordinates, inside,
get_element_type, filter_by_element_type, get_element_id,
optimize!, resize_sparse, resize_sparsevec
import FEMBase: get_unknown_field_name, get_unknown_field_dimension,
assemble!, update!, initialize!

Expand Down Expand Up @@ -107,15 +95,14 @@ end
include("deprecations.jl")

export SparseMatrixCOO, SparseVectorCOO, optimize!, resize_sparse
export Field, DCTI, DVTI, DCTV, DVTV, CCTI, CVTI, CCTV, CVTV, Increment
export DCTI, DVTI, DCTV, DVTV, CCTI, CVTI, CCTV, CVTV, Increment
export FieldProblem, BoundaryProblem, Problem, Node, Element, Assembly
export Poi1, Seg2, Seg3, Tri3, Tri6, Tri7, Quad4, Quad8, Quad9,
Tet4, Tet10, Pyr5, Wedge6, Wedge15, Hex8, Hex20, Hex27
export update!, add_elements!, get_unknown_field_name, add!,
is_field_problem, is_boundary_problem, get_gdofs,
initialize!, get_integration_points, group_by_element_type,
get_unknown_field_dimension, get_connectivity

export get_nonzero_rows, get_local_coordinates, inside, IP, get_element_type,
get_elements, AbstractProblem, IntegrationPoint, filter_by_element_type,
get_element_id, get_nonzero_columns, resize_sparse, resize_sparsevec
Expand Down
2 changes: 1 addition & 1 deletion src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ function update_xdmf!(xdmf::Xdmf, problem::Problem, time::Float64, fields::Vecto
info("Xdmf: Saving topology of $nelements elements total, $nelement_types different element types.")

for element_type in element_types
elements = filter_by_element_type(element_type, all_elements)
elements = collect(filter_by_element_type(element_type, all_elements))
nelements = length(elements)
info("Xdmf: $nelements elements of type $element_type")
sort!(elements, by=get_element_id)
Expand Down
2 changes: 1 addition & 1 deletion src/postprocess_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Return node ids + vector of values
function get_nodal_vector(elements::Vector, field_name::AbstractString, time::Float64)
f = Dict()
for element in elements
for (c, v) in zip(get_connectivity(element), element[field_name](time))
for (c, v) in zip(get_connectivity(element), element(field_name, time))
if haskey(f, c)
@assert isapprox(f[c], v)
end
Expand Down
22 changes: 11 additions & 11 deletions src/problems_contact_2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function assemble!(problem::Problem{Contact}, time::Float64, ::Type{Val{1}}, ::T
la1 = slave_element("lambda", time)
n1 = slave_element("normal", time)
t1 = slave_element("tangent", time)
x1 = X1 + u1
x1 = map(+, X1, u1)

contact_area = 0.0
contact_error = 0.0
Expand Down Expand Up @@ -116,7 +116,7 @@ function assemble!(problem::Problem{Contact}, time::Float64, ::Type{Val{1}}, ::T
nm = length(master_element)
X2 = master_element("geometry", time)
u2 = master_element("displacement", time)
x2 = X2 + u2
x2 = map(+, X2, u2)

# 3.3. loop integration points of one integration segment and calculate
# local mortar matrices
Expand All @@ -136,20 +136,20 @@ function assemble!(problem::Problem{Contact}, time::Float64, ::Type{Val{1}}, ::T
Phi = Ae*N1

# project gauss point from slave element to master element in direction n_s
X_s = N1*X1 # coordinate in gauss point
n_s = N1*n1 # normal direction in gauss point
t_s = N1*t1 # tangent condition in gauss point
X_s = interpolate(N1, X1) # coordinate in gauss point
n_s = interpolate(N1, n1) # normal direction in gauss point
t_s = interpolate(N1, t1) # tangent condition in gauss point
n_s /= norm(n_s)
t_s /= norm(t_s)
xi_m = project_from_slave_to_master(master_element, X_s, n_s, time)
N2 = vec(get_basis(master_element, xi_m, time))
X_m = N2*X2
X_m = interpolate(N2, X2)

u_s = N1*u1
u_m = N2*u2
x_s = X_s + u_s
x_m = X_m + u_m
la_s = Phi*la1
u_s = interpolate(N1, u1)
u_m = interpolate(N2, u2)
x_s = map(+, X_s, u_s)
x_m = map(+, X_m, u_m)
la_s = interpolate(Phi, la1)

# virtual work
De += w*Phi*N1'
Expand Down
61 changes: 33 additions & 28 deletions src/problems_contact_2d_autodiff.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@ xi
projected master
"""
function project_from_master_to_slave{E<:MortarElements2D}(
function project_from_master_to_slave_ad{E<:MortarElements2D}(
slave_element::Element{E}, x1_::DVTI, n1_::DVTI, x2::Vector;
tol=1.0e-10, max_iterations=20, debug=false)

x1(xi1) = vec(get_basis(slave_element, [xi1], time))*x1_
dx1(xi1) = vec(get_dbasis(slave_element, [xi1], time))*x1_
n1(xi1) = vec(get_basis(slave_element, [xi1], time))*n1_
dn1(xi1) = vec(get_dbasis(slave_element, [xi1], time))*n1_
""" Multiply basis / dbasis at `xi` with field. """
function mul(func, xi, field)
B = func(slave_element, [xi], time)
return sum(B[i]*field[i] for i=1:length(B))
end

x1(xi1) = mul(get_basis, xi1, x1_)
dx1(xi1) = mul(get_dbasis, xi1, x1_)
n1(xi1) = mul(get_basis, xi1, n1_)
dn1(xi1) = mul(get_dbasis, xi1, n1_)
cross2(a, b) = cross([a; 0], [b; 0])[3]
R(xi1) = cross2(x1(xi1)-x2, n1(xi1))
dR(xi1) = cross2(dx1(xi1), n1(xi1)) + cross2(x1(xi1)-x2, dn1(xi1))
Expand Down Expand Up @@ -62,12 +68,12 @@ function project_from_master_to_slave{E<:MortarElements2D}(

end

function project_from_slave_to_master{E<:MortarElements2D}(
master_element::Element{E}, x1::Vector, n1::Vector, x2_::DVTI;
function project_from_slave_to_master_ad{E<:MortarElements2D}(
master_element::Element{E}, x1, n1, x2_;
tol=1.0e-10, max_iterations=20)

x2(xi2) = vec(get_basis(master_element, [xi2], time))*x2_
dx2(xi2) = vec(get_dbasis(master_element, [xi2], time))*x2_
x2(xi2) = interpolate(vec(get_basis(master_element, [xi2], time)), x2_)
dx2(xi2) = interpolate(vec(get_dbasis(master_element, [xi2], time)), x2_)
cross2(a, b) = cross([a; 0], [b; 0])[3]
R(xi2) = cross2(x2(xi2)-x1, n1)
dR(xi2) = cross2(dx2(xi2), n1)
Expand Down Expand Up @@ -119,8 +125,7 @@ function assemble!(problem::Problem{Contact}, time::Float64,
push!(S, conn...)
gdofs = get_gdofs(element, field_dim)
X_el = element("geometry", time)
u_el = Field(Vector[u[:,i] for i in conn])
x_el = X_el + u_el
x_el = tuple( (X_el[i] + u[:,j] for (i,j) in enumerate(conn))... )
#=
for ip in get_integration_points(element, 3)
dN = get_dbasis(element, ip, time)
Expand Down Expand Up @@ -157,10 +162,10 @@ function assemble!(problem::Problem{Contact}, time::Float64,

slave_element_nodes = get_connectivity(slave_element)
X1 = slave_element("geometry", time)
u1 = Field(Vector[u[:,i] for i in slave_element_nodes])
x1 = X1 + u1
la1 = Field(Vector[la[:,i] for i in slave_element_nodes])
n1 = Field(Vector[normals[:,i] for i in slave_element_nodes])
u1 = ((u[:,i] for i in slave_element_nodes)...)
x1 = ((Xi+ui for (Xi,ui) in zip(X1,u1))...)
la1 = ((la[:,i] for i in slave_element_nodes)...)
n1 = ((normals[:,i] for i in slave_element_nodes)...)
nnodes = size(slave_element, 2)

# construct dual basis
Expand All @@ -170,12 +175,12 @@ function assemble!(problem::Problem{Contact}, time::Float64,

master_element_nodes = get_connectivity(master_element)
X2 = master_element("geometry", time)
u2 = Field(Vector[u[:,i] for i in master_element_nodes])
x2 = X2 + u2
u2 = ((u[:,i] for i in master_element_nodes)...)
x2 = ((Xi+ui for (Xi,ui) in zip(X2,u2))...)

# calculate segmentation: we care only about endpoints
xi1a = project_from_master_to_slave(slave_element, x1, n1, x2[1])
xi1b = project_from_master_to_slave(slave_element, x1, n1, x2[2])
xi1a = project_from_master_to_slave_ad(slave_element, field(x1), field(n1), x2[1])
xi1b = project_from_master_to_slave_ad(slave_element, field(x1), field(n1), x2[2])
xi1 = clamp.([xi1a; xi1b], -1.0, 1.0)
l = 1/2*abs(xi1[2]-xi1[1])
isapprox(l, 0.0) && continue # no contribution in this master element
Expand All @@ -200,17 +205,17 @@ function assemble!(problem::Problem{Contact}, time::Float64,

master_element_nodes = get_connectivity(master_element)
X2 = master_element("geometry", time)
u2 = Field(Vector[u[:,i] for i in master_element_nodes])
x2 = X2 + u2
u2 = ((u[:,i] for i in master_element_nodes)...)
x2 = ((Xi+ui for (Xi,ui) in zip(X2,u2))...)

#x1_midpoint = 1/2*(x1[1]+x1[2])
#x2_midpoint = 1/2*(x2[1]+x2[2])
#distance = ForwardDiff.get_value(norm(x2_midpoint - x1_midpoint))
#distance > props.maximum_distance && continue

# calculate segmentation: we care only about endpoints
xi1a = project_from_master_to_slave(slave_element, x1, n1, x2[1])
xi1b = project_from_master_to_slave(slave_element, x1, n1, x2[2])
xi1a = project_from_master_to_slave_ad(slave_element, field(x1), field(n1), x2[1])
xi1b = project_from_master_to_slave_ad(slave_element, field(x1), field(n1), x2[2])
xi1 = clamp.([xi1a; xi1b], -1.0, 1.0)
l = 1/2*abs(xi1[2]-xi1[1])
isapprox(l, 0.0) && continue # no contribution in this master element
Expand All @@ -229,15 +234,15 @@ function assemble!(problem::Problem{Contact}, time::Float64,
xi = ip.coords[1]
xi_s = dot([1/2*(1-xi); 1/2*(1+xi)], xi1)
N1 = vec(get_basis(slave_element, xi_s, time))
x_s = N1*x1 # coordinate in gauss point
n_s = N1*n1 # normal direction in gauss point
x_s = interpolate(N1, x1) # coordinate in gauss point
n_s = interpolate(N1, n1) # normal direction in gauss point
t_s = Q'*n_s # tangent direction in gauss point
xi_m = project_from_slave_to_master(master_element, x_s, n_s, x2)
xi_m = project_from_slave_to_master_ad(master_element, x_s, n_s, x2)
N2 = vec(get_basis(master_element, xi_m, time))
x_m = N2*x2
x_m = interpolate(N2, x2)
Phi = Ae*N1

la_s = Phi*la1 # traction force in gauss point
la_s = interpolate(Phi, la1) # traction force in gauss point
gn = -dot(n_s, x_s - x_m) # normal gap

fc[:,slave_element_nodes] += w*la_s*N1'
Expand Down
36 changes: 18 additions & 18 deletions src/problems_contact_3d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ function create_contact_segmentation(slave_element, master_elements, x0, n0, tim
result = []
x1 = slave_element("geometry", time)
if deformed
x1 += slave_element("displacement", time)
x1 = map(+, x1, slave_element("displacement", time))
end
S = Vector[project_vertex_to_auxiliary_plane(p, x0, n0) for p in x1]
for master_element in master_elements
x2 = master_element("geometry", time)
if deformed
x2 += master_element("displacement", time)
x2 = map(+, x2, master_element("displacement", time))
end
M = Vector[project_vertex_to_auxiliary_plane(p, x0, n0) for p in x2]
P = get_polygon_clip(S, M, n0)
Expand All @@ -115,7 +115,7 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri3}, time
nsl = length(slave_element)
X1 = slave_element("geometry", time)
u1 = slave_element("displacement", time)
x1 = X1 + u1
x1 = map(+, X1, u1)
n1 = slave_element("normal", time)
la = slave_element("lambda", time)

Expand All @@ -124,8 +124,8 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri3}, time
# project slave nodes to auxiliary plane (x0, Q)
xi = get_mean_xi(slave_element)
N = vec(get_basis(slave_element, xi, time))
x0 = N*X1
n0 = N*n1
x0 = interpolate(N, X1)
n0 = interpolate(N, n1)

# create contact segmentation
segmentation = create_contact_segmentation(slave_element, slave_element("master elements", time), x0, n0, time)
Expand All @@ -147,7 +147,7 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri3}, time
# loop integration cells
for cell in get_cells(P, C0)
virtual_element = Element(Tri3, Int[])
update!(virtual_element, "geometry", cell)
update!(virtual_element, "geometry", tuple(cell...))
for ip in get_integration_points(virtual_element, 3)
detJ = virtual_element(ip, time, Val{:detJ})
w = ip.weight*detJ
Expand All @@ -173,7 +173,7 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri3}, time
nm = length(master_element)
X2 = master_element("geometry", time)
u2 = master_element("displacement", time)
x2 = X2 + u2
x2 = map(+, X2, u2)

De = zeros(nsl, nsl)
Me = zeros(nsl, nm)
Expand All @@ -183,7 +183,7 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri3}, time
# loop integration cells
for cell in get_cells(P, C0)
virtual_element = Element(Tri3, Int[])
update!(virtual_element, "geometry", cell)
update!(virtual_element, "geometry", tuple(cell...))
# loop integration point of integration cell
for ip in get_integration_points(virtual_element, 3)

Expand All @@ -202,8 +202,8 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri3}, time
De += w*Phi*N1'
Me += w*Phi*N2'

x_s = N1*(X1+u1)
x_m = N2*(X2+u2)
x_s = interpolate(N1, map(+,X1,u1))
x_m = interpolate(N2, map(+,X2,u2))
ge += w*vec((x_m-x_s)*Phi')

end # integration points done
Expand Down Expand Up @@ -282,8 +282,8 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri6}, time
# create auxiliary plane
xi = get_mean_xi(sub_slave_element)
N = vec(get_basis(sub_slave_element, xi, time))
x0 = N*X1
n0 = N*n1
x0 = interpolate(N, X1)
n0 = interpolate(N, n1)

# project slave nodes to auxiliary plane
S = Vector[project_vertex_to_auxiliary_plane(p, x0, n0) for p in X1]
Expand Down Expand Up @@ -323,7 +323,7 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri6}, time
# 4. loop integration cells
for cell in get_cells(P, C0)
virtual_element = Element(Tri3, Int[])
update!(virtual_element, "geometry", cell)
update!(virtual_element, "geometry", tuple(cell...))
for ip in get_integration_points(virtual_element, 3)
detJ = virtual_element(ip, time, Val{:detJ})
w = ip.weight*detJ
Expand Down Expand Up @@ -358,8 +358,8 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri6}, time
# create auxiliary plane
xi = get_mean_xi(sub_slave_element)
N = vec(get_basis(sub_slave_element, xi, time))
x0 = N*X1
n0 = N*n1
x0 = interpolate(N, X1)
n0 = interpolate(N, n1)

# project slave nodes to auxiliary plane
S = Vector[project_vertex_to_auxiliary_plane(p, x0, n0) for p in X1]
Expand Down Expand Up @@ -406,7 +406,7 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri6}, time
# 4. loop integration cells
for cell in get_cells(P, C0)
virtual_element = Element(Tri3, Int[])
update!(virtual_element, "geometry", cell)
update!(virtual_element, "geometry", tuple(cell...))

# 5. loop integration point of integration cell
for ip in get_integration_points(virtual_element, 3)
Expand All @@ -429,8 +429,8 @@ function assemble!(problem::Problem{Contact}, slave_element::Element{Tri6}, time

us = slave_element("displacement", time)
um = master_element("displacement", time)
xs = N1*(Xs+us)
xm = N2*(Xs+um)
xs = interpolate(N1, map(+,Xs,us))
xm = interpolate(N2, map(+,Xs,um))
ge += w*vec((xm-xs)*Phi')

end # integration points done
Expand Down
15 changes: 15 additions & 0 deletions src/problems_dirichlet.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ function Dirichlet()
Dirichlet(:incremental, false, false, 1)
end

""" Return dual basis transformation matrix Ae. """
function get_dualbasis(element::Element, time::Float64, order=1)
nnodes = length(element)
De = zeros(nnodes, nnodes)
Me = zeros(nnodes, nnodes)
for ip in get_integration_points(element, order)
detJ = element(ip, time, Val{:detJ})
w = ip.weight*detJ
N = element(ip, time)
De += w*diagm(vec(N))
Me += w*N'*N
end
return De, Me, De*inv(Me)
end

function get_formulation_type(problem::Problem{Dirichlet})
return problem.properties.formulation
end
Expand Down
Loading

0 comments on commit d7bef41

Please sign in to comment.