From 02277b3aabe045f4ef3a9bf42f53ffb6a134295e Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Thu, 3 Aug 2017 18:41:59 +0300 Subject: [PATCH] Define functions more loosely Let compiler determine input types --- src/calculate_mortar_assembly.jl | 64 +++++++++++++++++++++++++++++--- src/calculate_mortar_matrices.jl | 8 +--- src/calculate_normals.jl | 6 +-- src/calculate_projections.jl | 48 ++++++++++++++++++++---- src/calculate_segments.jl | 8 +--- 5 files changed, 105 insertions(+), 29 deletions(-) diff --git a/src/calculate_mortar_assembly.jl b/src/calculate_mortar_assembly.jl index 69d52a2..0094d11 100644 --- a/src/calculate_mortar_assembly.jl +++ b/src/calculate_mortar_assembly.jl @@ -14,17 +14,69 @@ function of package. Relation between matrices is ``D u_s = M u_m``, where # Example -```julia +Calculate mortar matrices for simple problem in README.md + +```jldoctest ex1 +Xs = Dict(1 => [0.0, 1.0], 2 => [5/4, 1.0], 3 => [2.0, 1.0]) +Xm = Dict(4 => [0.0, 1.0], 5 => [1.0, 1.0], 6 => [2.0, 1.0]) +coords = merge(Xm , Xs) +Es = Dict(1 => [1, 2], 2 => [2, 3]) +Em = Dict(3 => [4, 5], 4 => [5, 6]) +elements = merge(Es, Em) +element_types = Dict(1 => :Seg2, 2 => :Seg2, 3 => :Seg2, 4 => :Seg2) +slave_element_ids = [1, 2] +master_element_ids = [3, 4] s, m, D, M = calculate_mortar_assembly(elements, element_types, coords, slave_element_ids, master_element_ids) + +# output + +([1, 2, 3], [4, 5, 6], + [1, 1] = 0.416667 + [2, 1] = 0.208333 + [1, 2] = 0.208333 + [2, 2] = 0.666667 + [3, 2] = 0.125 + [2, 3] = 0.125 + [3, 3] = 0.25, + [1, 4] = 0.366667 + [2, 4] = 0.133333 + [1, 5] = 0.25625 + [2, 5] = 0.65 + [3, 5] = 0.09375 + [1, 6] = 0.00208333 + [2, 6] = 0.216667 + [3, 6] = 0.28125) + +``` + +`s` and `m` contains slave and master dofs: +```jldoctest ex1 +julia> s, m +([1, 2, 3], [4, 5, 6]) +``` + +`D` is slave side mortar matrix: +```jldoctest ex1 +julia> full(D[s,s]) +3×3 Array{Float64,2}: + 0.416667 0.208333 0.0 + 0.208333 0.666667 0.125 + 0.0 0.125 0.25 +``` + +`M` is master side mortar matrix: +```jldoctest ex1 +julia> full(M[s,m]) +3×3 Array{Float64,2}: + 0.366667 0.25625 0.00208333 + 0.133333 0.65 0.216667 + 0.0 0.09375 0.28125 ``` """ -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}) +function calculate_mortar_assembly(elements, element_types, coords, + slave_element_ids, master_element_ids) S = Int[] M = Int[] for sid in slave_element_ids diff --git a/src/calculate_mortar_matrices.jl b/src/calculate_mortar_matrices.jl index fb92413..dcd6a10 100644 --- a/src/calculate_mortar_matrices.jl +++ b/src/calculate_mortar_matrices.jl @@ -44,12 +44,8 @@ De, Me = calculate_mortar_matrices(1, elements, element_types, ``` """ -function calculate_mortar_matrices(slave_element_id::Int, - elements::Dict{Int, Vector{Int}}, - element_types::Dict{Int, Symbol}, - coords::Dict{Int, Vector{Float64}}, - normals::Dict{Int, Vector{Float64}}, - segmentation::MortarSegmentation) +function calculate_mortar_matrices(slave_element_id, elements, element_types, + coords, normals, segmentation) @assert element_types[slave_element_id] == :Seg2 # Initialization + calculate jacobian De = zeros(2, 2) diff --git a/src/calculate_normals.jl b/src/calculate_normals.jl index c84aaa9..d9d9525 100644 --- a/src/calculate_normals.jl +++ b/src/calculate_normals.jl @@ -31,10 +31,8 @@ Dict{Int64,Array{Float64,1}} with 3 entries: ``` """ -function calculate_normals{T<:Integer,P<:AbstractFloat}(elements::Dict{T, Vector{T}}, - element_types::Dict{T, Symbol}, - X::Dict{T, Vector{P}}) - normals = Dict{T, Vector{P}}() +function calculate_normals(elements, element_types, X) + normals = similar(X) for (elid, elcon) in elements @assert element_types[elid] == :Seg2 d = X[elcon[2]] - X[elcon[1]] diff --git a/src/calculate_projections.jl b/src/calculate_projections.jl index 39a4746..bb27e78 100644 --- a/src/calculate_projections.jl +++ b/src/calculate_projections.jl @@ -5,12 +5,28 @@ project_from_slave_to_master(Val{:Seg2}, xs, ns, xm1, xm2) Find the projection of a slave node `xs`, having normal vector `ns`, onto master -elements with nodes (`xm1`, `xm2`). +elements with nodes (`xm1`, `xm2`). Returns master element dimensionless parameter +xi, that is, + + xm = 1/2*(1-xi)*xm1 + 1/2*(1+xi)*xm2 + +# Example + +```jldoctest +xm1 = [7.0, 2.0] +xm2 = [4.0, -2.0] +xs = [0.0, 0.0] +ns = [3.0/5.0, -4.0/5.0] +xi2 = project_from_slave_to_master(Val{:Seg2}, xs, ns, xm1, xm2) +round(xi2, 6) + +# output + +1.833333 +``` """ -function project_from_slave_to_master{T<:Number}(::Type{Val{:Seg2}}, xs::Vector{T}, - ns::Vector{T}, xm1::Vector{T}, - xm2::Vector{T}) +function project_from_slave_to_master(::Type{Val{:Seg2}}, xs, ns, xm1, xm2) nom = ns[1]*(xm1[2] + xm2[2] - 2*xs[2]) - ns[2]*(xm1[1] + xm2[1] - 2*xs[1]) denom = ns[1]*(xm1[2] - xm2[2]) + ns[2]*(xm2[1] - xm1[1]) return nom/denom @@ -21,11 +37,29 @@ end Find the projection of a master node `xm`, to the slave surface with nodes (`xs1`, `xs2`), in direction of slave surface normal defined by (`ns1`, `ns2`). +Returns slave element dimensionless parameter, that is, to find coordinates +in slave side: + + xs = 1/2*(1-xi)*xs1 + 1/2*(1+xi)*xs2 + +# Example + +```jldoctest +xm = [4.0, -2.0] +xs1 = [0.0, 0.0] +xs2 = [4.0, 3.0] +ns1 = [3.0/5.0, -4.0/5.0] +ns2 = sqrt(2)/2*[1, -1] +xi1 = project_from_master_to_slave(Val{:Seg2}, xm, xs1, xs2, ns1, ns2) +round(xi1, 6) + +# output + +-0.281575 +``` """ -function project_from_master_to_slave{T<:Number}(::Type{Val{:Seg2}}, xm::Vector{T}, - xs1::Vector{T}, xs2::Vector{T}, - ns1::Vector{T}, ns2::Vector{T}) +function project_from_master_to_slave(::Type{Val{:Seg2}}, xm, xs1, xs2, ns1, ns2) # Special case when normal is constant. Then we have # unique solution and linear equation to solve. diff --git a/src/calculate_segments.jl b/src/calculate_segments.jl index c13a13e..9714c36 100644 --- a/src/calculate_segments.jl +++ b/src/calculate_segments.jl @@ -52,12 +52,8 @@ system is: x_stop = 1/2*(1-xi[2])*xs1 + 1/2*(1+xi[2])*xs2 """ -function calculate_segments(slave_element_ids::Vector{Int}, - master_element_ids::Vector{Int}, - elements::Dict{Int, Vector{Int}}, - element_types::Dict{Int, Symbol}, - coords::Dict{Int, Vector{Float64}}, - normals::Dict{Int, Vector{Float64}}) +function calculate_segments(slave_element_ids, master_element_ids, elements, + element_types, coords, normals) S = MortarSegmentation() for sid in slave_element_ids @assert element_types[sid] == :Seg2