Files
JuliaFEM.jl/src/problems.jl
T
Jukka Aho e364a538ed - Updated FieldSet + developer guide
- Verification of heat problem
2015-10-20 15:54:47 +03:00

146 lines
3.8 KiB
Julia

# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
abstract Problem
abstract BoundaryProblem <: Problem
abstract FieldProblem <: Problem
get_equations(pr::Problem) = pr.equations
function get_dimension(pr::Type{Problem})
throw("Unable to determine problem dimension for problem $pr")
end
function get_equation(pr::Type{Problem}, el::Type{Element})
throw("Could not find corresponding equation for element $el in problem $pr")
end
"""
Add new element to problem
"""
function add_element!(problem::Problem, element::Element)
equation = get_equation(typeof(problem), typeof(element))
push!(problem.equations, equation(element))
end
function Base.push!(problem::Problem, element::Element)
equation = get_equation(typeof(problem), typeof(element))
push!(problem.equations, equation(element))
end
"""
Return total number of basis functions in problem
"""
function get_number_of_basis_functions(pr::Problem)
conn = Int[]
for eq in get_equations(pr)
append!(conn, get_connectivity(eq))
end
length(unique(conn))
end
"""
Problem matrix size dimension
"""
function get_matrix_dimension(pr::Problem)
get_dimension(typeof(pr))*get_number_of_basis_functions(pr)
end
"""
Assign global dofs for element. This doesn't do any reordering.
"""
function set_global_dofs!(pr::Problem)
#ndim = get_dimension(pr)*get_number_of_basis_functions(pr)
#ndim = get_matrix_dimension(pr)
dim = get_dimension(typeof(pr))
nconn = get_number_of_basis_functions(pr)
ndim = dim*nconn
Logging.debug("Problem (matrix) dimension: $ndim")
gdofs = reshape(collect(1:ndim), dim, nconn)
for eq in get_equations(pr)
lconn = get_connectivity(eq)
gconn = gdofs[:, lconn][:]
set_global_dofs!(eq, gconn)
end
end
""" Return unique list of connectivity (i.e. node ids). """
function get_connectivity(problem::Problem)
connectivity = Int[]
for equation in get_equations(problem)
element = get_element(equation)
append!(connectivity, get_connectivity(element))
end
connectivity = unique(connectivity)
return connectivity
end
"""
Calculate global dofs for equations, maybe using some bandwidth
minimizing or fill reducing algorithm
"""
function calculate_global_dofs(pr::Problem)
conn = get_connectivity(pr)
dim = get_dimension(typeof(pr))
ndofs = dim*length(conn)
Logging.debug("total dofs: $ndofs")
mconn = maximum(conn)
gdofs = reshape(collect(1:mconn), dim, mconn)
dofmap = Dict{Int64, Array{Int64, 1}}()
for (i, c) in enumerate(conn)
dofmap[c] = gdofs[:, i]
end
return dofmap
end
"""
Assign global dofs for equations.
"""
function assign_global_dofs!(pr::Problem, dofmap)
for eq in get_equations(pr)
el = get_element(eq)
c = get_connectivity(el)
#gdofs = [dofmap[ci] for ci in c]
gdofs = Int64[]
for ci in c
append!(gdofs, dofmap[ci])
end
set_global_dofs!(eq, gdofs)
end
end
function get_lhs(pr::Problem, t::Float64)
I = Int64[]
J = Int64[]
V = Float64[]
dim = get_dimension(typeof(pr))
for eq in filter(has_lhs, get_equations(pr))
dofs = get_global_dofs(eq)
lhs = integrate_lhs(eq, t)
for (li, i) in enumerate(dofs)
for (lj, j) in enumerate(dofs)
push!(I, i)
push!(J, j)
push!(V, lhs[li, lj])
end
end
end
return I, J, V
end
function get_rhs(pr::Problem, t::Float64)
I = Int64[]
V = Float64[]
dim = get_dimension(typeof(pr))
for eq in filter(has_rhs, get_equations(pr))
dofs = get_global_dofs(eq)
rhs = integrate_rhs(eq, t)
for (li, i) in enumerate(dofs)
push!(I, i)
push!(V, rhs[li])
end
end
return I, V
end