Files
JuliaFEM.jl/src/mortar.jl
T

89 lines
2.7 KiB
Julia
Raw Normal View History

2015-11-12 07:16:25 +02:00
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
2015-11-18 01:19:04 +02:00
# Mortar equations
2015-11-12 07:16:25 +02:00
abstract MortarEquation <: Equation
2015-10-20 15:54:47 +03:00
2015-11-18 01:19:04 +02:00
function get_unknown_field_name(equation::MortarEquation)
return "reaction force"
end
""" Mortar boundary condition element for 2-dimensional problem, 2 node line segment. """
type MBC2D2 <: MortarEquation
element :: MSeg2
integration_points :: Vector{IntegrationPoint}
end
function Base.size(equation::MBC2D2)
return (1, 2)
end
function Base.convert(::Type{MortarEquation}, element::MSeg2)
return MBC2D2(element, get_default_integration_points(element))
end
# Mortar problem
2015-10-20 15:54:47 +03:00
"""
2015-11-12 07:16:25 +02:00
Parameters
----------
node_csys
coordinate system in node, normal + tangent + "binormal"
2015-11-18 01:19:04 +02:00
in 3d 3x3 matrix, in 2d 2x2 matrix, respectively
2015-10-20 15:54:47 +03:00
"""
2015-11-12 07:16:25 +02:00
type MortarProblem <: BoundaryProblem
unknown_field_name :: ASCIIString
unknown_field_dimension :: Int
equations :: Vector{MortarEquation}
2015-10-20 15:54:47 +03:00
end
2015-11-18 01:19:04 +02:00
function MortarProblem(dimension::Int=1, equations=[])
MortarProblem("reaction force", dimension, equations)
2015-10-20 15:54:47 +03:00
end
2015-11-18 01:19:04 +02:00
# Mortar projection calculation
""" Find master or "mortar" elements for this slave element. """
function get_master_elements(element::MortarElement)
return element.master_elements
2015-10-20 15:54:47 +03:00
end
2015-11-18 01:19:04 +02:00
function assemble!(assembly::Assembly, equation::MortarEquation, time::Number=0.0, problem=nothing)
2015-11-12 07:16:25 +02:00
slave_element = get_element(equation)
2015-11-18 01:19:04 +02:00
master_elements = get_master_elements(slave_element)
slave_basis = get_basis(slave_element)
detJ = det(slave_basis)
dim = size(equation, 1) # number of nodes
slave_dofs = get_gdofs(slave_element, dim)
2015-11-12 07:16:25 +02:00
for master_element in master_elements
2015-11-18 01:19:04 +02:00
master_dofs = get_gdofs(master_element, dim)
xi1a = project_from_master_to_slave(slave_element, master_element, [-1.0])
xi1b = project_from_master_to_slave(slave_element, master_element, [ 1.0])
xi1 = clamp([xi1a xi1b], -1.0, 1.0)
l = 1/2*(xi1[2]-xi1[1])
if abs(l) < 1.0e-6
warn("No contribution")
continue # no contribution
end
master_basis = get_basis(master_element)
for ip in get_integration_points(equation)
w = ip.weight*detJ(ip)*l
# integration point on slave side segment
xi_gauss = 1/2*(1-ip.xi)*xi1[1] + 1/2*(1+ip.xi)*xi1[2]
# projected integration point
xi_projected = project_from_slave_to_master(slave_element, master_element, xi_gauss)
# add contribution to left hand side
N1 = slave_basis(xi_gauss, time)
N2 = master_basis(xi_projected, time)
add!(assembly.lhs, slave_dofs, slave_dofs, w*N1'*N1)
add!(assembly.lhs, slave_dofs, master_dofs, -w*N1'*N2)
2015-11-12 07:16:25 +02:00
end
end
2015-10-20 15:54:47 +03:00
end
2015-11-12 07:16:25 +02:00