-
Notifications
You must be signed in to change notification settings - Fork 7
/
calculate_mortar_assembly.jl
75 lines (70 loc) · 2.48 KB
/
calculate_mortar_assembly.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/Mortar2D.jl/blob/master/LICENSE
"""
calculate_mortar_assembly(elements::Dict{Int, Vector{Int}},
element_types::Dict{Int, Symbol},
coords::Dict{Int, Vector{Float64}},
slave_element_ids::Vector{Int},
master_element_ids::Vector{Int})
Given data, calculate projection matrix `P`. This is the main function of
package.
Matrix ``P`` is defined as a projection between slave and master surface,
i.e.
```math
D u_s = M u_m \\Rightarrow u_s = D^{-1} M u_m = P u_m.
```
"""
function calculate_mortar_assembly(elements::Dict{Int, Vector{Int}},
element_types::Dict{Int, Symbol},
coords::Dict{Int, Vector{Float64}},
slave_element_ids::Vector{Int},
master_element_ids::Vector{Int})
S = Int[]
M = Int[]
for sid in slave_element_ids
push!(S, elements[sid]...)
end
for mid in master_element_ids
push!(M, elements[mid]...)
end
S = sort(unique(S))
M = sort(unique(M))
ns = length(S)
nm = length(M)
normals = calculate_normals(elements, element_types, coords)
segmentation = calculate_segments(slave_element_ids, master_element_ids,
elements, element_types, coords, normals)
D_I = Int[]
D_J = Int[]
D_V = Float64[]
M_I = Int[]
M_J = Int[]
M_V = Float64[]
for sid in slave_element_ids
mids = [mid for (mid, xi) in segmentation[sid]]
De, Me = calculate_mortar_matrices(sid, elements, element_types,
coords, normals, segmentation)
for (i,I) in enumerate(elements[sid])
for (j,J) in enumerate(elements[sid])
push!(D_I, I)
push!(D_J, J)
push!(D_V, De[i,j])
end
end
for mid in mids
for (i,I) in enumerate(elements[sid])
for (j,J) in enumerate(elements[mid])
push!(M_I, I)
push!(M_J, J)
push!(M_V, Me[mid][i,j])
end
end
end
end
D = sparse(D_I, D_J, D_V)
Df = cholfact(1/2*(D+D')[S,S])
M_ = sparse(M_I, M_J, M_V)
P = Df \ M_[S,M]
SparseArrays.droptol!(P, 1.0e-12)
return P
end