mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-07 03:36:23 +00:00
e364a538ed
- Verification of heat problem
146 lines
3.8 KiB
Julia
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
|
|
|