Files
JuliaFEM.jl/src/problems_dirichlet.jl
T

195 lines
6.2 KiB
Julia

# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
"""
Problem u(X) = u₀ in Γ(d)
"""
type Dirichlet <: BoundaryProblem
formulation :: Symbol
variational :: Bool
dual_basis :: Bool
order :: Int
end
function Dirichlet()
Dirichlet(:incremental, false, false, 1)
end
function get_unknown_field_name(::Type{Dirichlet})
return "reaction force"
end
function get_formulation_type(problem::Problem{Dirichlet})
return problem.properties.formulation
end
function assemble!(problem::Problem{Dirichlet}, time::Float64=0.0;
auto_initialize=true)
# FIXME: boilerplate
if !isempty(problem.assembly)
warn("Assemble problem $(problem.name): problem.assembly is not empty and assembling, are you sure you know what are you doing?")
end
if isempty(problem.elements)
warn("Assemble problem $(problem.name): problem.elements is empty, no elements in problem?")
else
first_element = first(problem.elements)
unknown_field_name = get_unknown_field_name(problem)
if !haskey(first_element, unknown_field_name)
warn("Assemble problem $(problem.name): seems that problem is uninitialized.")
if auto_initialize
info("Initializing problem $(problem.name) at time $time automatically.")
initialize!(problem, time)
end
end
end
if method_exists(assemble_prehook!, Tuple{typeof(problem), Float64})
assemble_prehook!(problem, time)
end
if problem.properties.variational
for element in get_elements(problem)
assemble!(problem.assembly, problem, element, time)
end
else # nodal collocation
field_vals = Dict{Int64, Float64}()
field_name = get_parent_field_name(problem)
field_dim = get_unknown_field_dimension(problem)
for element in get_elements(problem)
gdofs = get_gdofs(problem, element)
for i=1:field_dim
haskey(element, field_name*" $i") || continue
ldofs = gdofs[i:field_dim:end]
xis = get_reference_coordinates(typeof(element.properties))
vals = Float64[]
for xi in xis
g = element(field_name*" $i", xi, time)
# u = u_prev + Δu ⇒ Δu = u - u_prev
if haskey(element, field_name)
g_prev = element(field_name, xi, time)
g -= g_prev[i]
end
push!(vals, g)
end
for (dof, g) in zip(ldofs, vals)
field_vals[dof] = g
end
end
end
for (k, v) in field_vals
push!(problem.assembly.C1, k, k, 1.0)
push!(problem.assembly.C2, k, k, 1.0)
push!(problem.assembly.g, k, 1, v)
end
end
if method_exists(assemble_posthook!, Tuple{typeof(problem), Float64})
assemble_posthook!(problem, time)
end
end
function assemble!(assembly::Assembly, problem::Problem{Dirichlet},
element::Element, time::Float64)
# get dimension and name of PARENT field
nnodes = length(element)
field_dim = get_unknown_field_dimension(problem)
field_name = get_parent_field_name(problem)
gdofs = get_gdofs(element, field_dim)
props = problem.properties
if problem.properties.dual_basis
De, Me, Ae = get_dualbasis(element, time)
else
Ae = eye(nnodes)
De = zeros(nnodes, nnodes)
for ip in get_integration_points(element, props.order)
N = element(ip, time)
detJ = element(ip, time, Val{:detJ})
De += ip.weight*N'*N*detJ
end
end
# left hand side
for i=1:field_dim
ldofs = gdofs[i:field_dim:end]
if haskey(element, field_name*" $i")
add!(assembly.C1, ldofs, ldofs, De)
add!(assembly.C2, ldofs, ldofs, De)
end
end
# right hand side
for ip in get_integration_points(element, props.order)
detJ = element(ip, time, Val{:detJ})
w = ip.weight*detJ
N = element(ip, time)
for i=1:field_dim
ldofs = gdofs[i:field_dim:end]
if haskey(element, field_name*" $i")
g = element(field_name*" $i", ip, time)
# u = u_prev + Δu ⇒ Δu = u - u_prev
if haskey(element, field_name)
g_prev = element(field_name, ip, time)
g -= g_prev[i]
end
add!(assembly.g, ldofs, w*g*Ae*N')
end
end
end
end
#=
function assemble!(assembly::Assembly, problem::Problem{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
=#