2015-10-09 23:45:28 +03:00
|
|
|
# This file is a part of JuliaFEM.
|
|
|
|
|
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
|
|
|
|
|
2015-12-23 17:39:53 +02:00
|
|
|
abstract DirichletProblem{T} <: AbstractProblem
|
|
|
|
|
abstract StandardBasis
|
2016-02-01 09:10:44 +02:00
|
|
|
abstract DualBasis
|
|
|
|
|
global const BiorthogonalBasis = DualBasis
|
2015-10-09 23:45:28 +03:00
|
|
|
|
2016-02-02 22:22:21 +02:00
|
|
|
type Dirichlet <: AbstractProblem
|
|
|
|
|
dual_basis :: Bool
|
2015-12-17 15:33:51 +02:00
|
|
|
end
|
2015-12-30 17:24:58 +02:00
|
|
|
|
2016-02-02 22:22:21 +02:00
|
|
|
function Dirichlet()
|
|
|
|
|
Dirichlet(true)
|
2015-10-09 23:45:28 +03:00
|
|
|
end
|
|
|
|
|
|
2016-02-02 22:22:21 +02:00
|
|
|
function assemble!(assembly::BoundaryAssembly, problem::BoundaryProblem{Dirichlet}, element::Element, time::Real)
|
|
|
|
|
|
|
|
|
|
@assert problem.properties.dual_basis
|
2015-12-23 17:39:53 +02:00
|
|
|
|
|
|
|
|
# get dimension and name of PARENT field
|
|
|
|
|
field_dim = problem.parent_field_dim
|
|
|
|
|
field_name = problem.parent_field_name
|
|
|
|
|
gdofs = get_gdofs(element, field_dim)
|
|
|
|
|
|
|
|
|
|
# calculate bi-orthogonal basis transformation matrix Ae
|
|
|
|
|
nnodes = size(element, 2)
|
|
|
|
|
De = zeros(nnodes, nnodes)
|
|
|
|
|
Me = zeros(nnodes, nnodes)
|
|
|
|
|
for ip in get_integration_points(element, Val{2})
|
|
|
|
|
w = ip.weight
|
|
|
|
|
J = get_jacobian(element, ip, time)
|
|
|
|
|
JT = transpose(J)
|
|
|
|
|
if size(JT, 2) == 1 # plane problem
|
|
|
|
|
w *= norm(JT)
|
|
|
|
|
else
|
|
|
|
|
w *= norm(cross(JT[:,1], JT[:,2]))
|
|
|
|
|
end
|
|
|
|
|
N = element(ip, time)
|
|
|
|
|
De += w*diagm(vec(N))
|
|
|
|
|
Me += w*N'*N
|
|
|
|
|
end
|
|
|
|
|
Ae = De*inv(Me)
|
|
|
|
|
|
|
|
|
|
# do the actual integration
|
|
|
|
|
for ip in get_integration_points(element, Val{2})
|
|
|
|
|
w = ip.weight
|
|
|
|
|
J = get_jacobian(element, ip, time)
|
|
|
|
|
JT = transpose(J)
|
|
|
|
|
if size(JT, 2) == 1 # plane problem
|
|
|
|
|
w *= norm(JT)
|
|
|
|
|
else
|
|
|
|
|
w *= norm(cross(JT[:,1], JT[:,2]))
|
|
|
|
|
end
|
|
|
|
|
N = element(ip, time)
|
|
|
|
|
Phi = (Ae*N')'
|
|
|
|
|
A = w*Phi'*N
|
2016-02-02 22:22:21 +02:00
|
|
|
A[abs(A) .< 1.0e-12] = 0
|
2015-12-23 17:39:53 +02:00
|
|
|
|
|
|
|
|
if haskey(element, field_name)
|
|
|
|
|
for i=1:field_dim
|
|
|
|
|
g = element(field_name, ip, time)
|
|
|
|
|
ldofs = gdofs[i:field_dim:end]
|
2016-02-01 09:10:44 +02:00
|
|
|
add!(assembly.C1, ldofs, ldofs, A)
|
2015-12-23 17:39:53 +02:00
|
|
|
add!(assembly.C2, ldofs, ldofs, A)
|
|
|
|
|
add!(assembly.g, ldofs, w*g*Phi')
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
for i=1:field_dim
|
|
|
|
|
ldofs = gdofs[i:field_dim:end]
|
|
|
|
|
if haskey(element, field_name*" $i")
|
|
|
|
|
g = element(field_name*" $i", ip, time)
|
2016-02-01 09:10:44 +02:00
|
|
|
add!(assembly.C1, ldofs, ldofs, A)
|
2015-12-23 17:39:53 +02:00
|
|
|
add!(assembly.C2, ldofs, ldofs, A)
|
|
|
|
|
add!(assembly.g, ldofs, w*g*Phi')
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2016-02-02 22:22:21 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
function assemble!(assembly::BoundaryAssembly, problem::BoundaryProblem{DirichletProblem}, element::Element, time::Real)
|
|
|
|
|
|
|
|
|
|
# get dimension and name of PARENT field
|
|
|
|
|
field_dim = problem.parent_field_dim
|
|
|
|
|
field_name = problem.parent_field_name
|
|
|
|
|
|
|
|
|
|
gdofs = get_gdofs(element, field_dim)
|
|
|
|
|
for ip in get_integration_points(element, Val{2})
|
|
|
|
|
w = ip.weight
|
|
|
|
|
J = get_jacobian(element, ip, time)
|
|
|
|
|
JT = transpose(J)
|
|
|
|
|
if size(JT, 2) == 1 # plane problem
|
|
|
|
|
w *= norm(JT)
|
|
|
|
|
else
|
|
|
|
|
w *= norm(cross(JT[:,1], JT[:,2]))
|
|
|
|
|
end
|
|
|
|
|
N = element(ip, time)
|
|
|
|
|
A = w*N'*N
|
|
|
|
|
|
|
|
|
|
if haskey(element, field_name)
|
|
|
|
|
# add all dimensions at once if defined
|
|
|
|
|
# element["blaa"] = 0.0
|
|
|
|
|
# or
|
|
|
|
|
# element["blaa"] = Vector{Float64}[[0.1, 0.2], [0.3, 0.4]]
|
|
|
|
|
g = element(field_name, ip, time)
|
|
|
|
|
if length(g) != length(N)
|
|
|
|
|
g = g*ones(length(N))
|
|
|
|
|
end
|
|
|
|
|
for i=1:field_dim
|
|
|
|
|
ldofs = gdofs[i:field_dim:end]
|
|
|
|
|
add!(assembly.C1, ldofs, ldofs, A)
|
|
|
|
|
add!(assembly.C2, ldofs, ldofs, A)
|
|
|
|
|
end
|
|
|
|
|
add!(assembly.g, gdofs, w*g*N)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
for i=1:field_dim
|
|
|
|
|
if haskey(element, field_name*" $i")
|
|
|
|
|
g = element(field_name*" $i", ip, time)
|
|
|
|
|
ldofs = gdofs[i:field_dim:end]
|
|
|
|
|
add!(assembly.C1, ldofs, ldofs, A)
|
|
|
|
|
add!(assembly.C2, ldofs, ldofs, A)
|
|
|
|
|
add!(assembly.g, ldofs, w*g*N)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|