Files
JuliaFEM.jl/src/heat.jl
T

186 lines
5.7 KiB
Julia
Raw Normal View History

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
# Heat problems
2015-10-28 04:29:14 +02:00
""" Heat equations.
Formulation
-----------
Field equation is:
ρc∂u/∂t = ∇⋅(k∇u) + f
Weak form is: find u∈U such that ∀v in V
∫k∇u∇v dx = ∫fv dx + ∫gv ds,
where
k = temperature thermal conductivity defined on volume elements
f = temperature load defined on volume elements
g = temperature flux defined on boundary elements
2015-10-28 04:29:14 +02:00
2016-07-01 02:55:56 +03:00
Parameters
----------
temperature thermal conductivity
temperature load
temperature flux
thermal conductivity
heat source
heat flux
heat transfer coefficient
external temperature
Formulations
------------
1D, 2D, 3D
2015-10-28 04:29:14 +02:00
References
----------
https://en.wikipedia.org/wiki/Heat_equation
2016-07-01 02:55:56 +03:00
https://en.wikipedia.org/wiki/Heat_capacity
https://en.wikipedia.org/wiki/Thermal_conduction
https://en.wikipedia.org/wiki/Thermal_conductivity
https://en.wikipedia.org/wiki/Thermal_diffusivity
https://en.wikipedia.org/wiki/Volumetric_heat_capacity
2015-10-28 04:29:14 +02:00
"""
type Heat <: FieldProblem
2016-07-01 02:55:56 +03:00
formulation :: ASCIIString
end
function Heat()
return Heat("3D")
end
function get_unknown_field_name(problem::Problem{Heat})
return "temperature"
end
2016-07-01 02:55:56 +03:00
function assemble!(assembly::Assembly, problem::Problem{Heat}, element::Element, time=0.0)
formulation = Val{Symbol(problem.properties.formulation)}
assemble!(assembly, problem, element, time, formulation)
end
2016-07-01 02:55:56 +03:00
# 3d heat problems
function assemble!{E}(assembly::Assembly, problem::Problem{Heat}, element::Element{E}, time, ::Type{Val{Symbol("3D")}})
info("Unknown element type $E for 3d heat problem!")
end
typealias Heat3DVolumeElements Union{Tet4, Tet10, Hex8}
typealias Heat3DSurfaceElements Union{Tri3, Tri6, Quad4}
function assemble!{E<:Heat3DVolumeElements}(assembly::Assembly, problem::Problem{Heat}, element::Element{E}, time, ::Type{Val{Symbol("3D")}})
gdofs = get_gdofs(problem, element)
field_name = get_unknown_field_name(problem)
nnodes = length(element)
K = zeros(nnodes, nnodes)
fq = zeros(nnodes)
for ip in get_integration_points(element)
detJ = element(ip, time, Val{:detJ})
w = ip.weight*detJ
N = element(ip, time)
if haskey(element, "$field_name thermal conductivity")
dN = element(ip, time, Val{:Grad})
k = element("$field_name thermal conductivity", ip, time)
K += w*k*dN'*dN
end
if haskey(element, "$field_name load")
f = element("$field_name load", ip, time)
fq += w*N'*f
end
end
T = vec(element[field_name](time))
fq -= K*T
add!(assembly.K, gdofs, gdofs, K)
add!(assembly.f, gdofs, fq)
end
function assemble!{E<:Heat3DSurfaceElements}(assembly::Assembly, problem::Problem{Heat}, element::Element{E}, time, ::Type{Val{Symbol("3D")}})
gdofs = get_gdofs(problem, element)
field_name = get_unknown_field_name(problem)
nnodes = length(element)
K = zeros(nnodes, nnodes)
fq = zeros(nnodes)
for ip in get_integration_points(element)
detJ = element(ip, time, Val{:detJ})
w = ip.weight*detJ
N = element(ip, time)
if haskey(element, "$field_name flux")
q = element("$field_name flux", ip, time)
fq += w*N'*q
end
if haskey(element, "$field_name heat transfer coefficient")
h = element("$field_name heat transfer coefficient", ip, time)
Tu = element("$field_name external temperature", ip, time)
K += w*h*N'*N
fq += w*N'*h*Tu
end
end
T = vec(element[field_name](time))
fq -= K*T
add!(assembly.K, gdofs, gdofs, K)
add!(assembly.f, gdofs, fq)
end
# 2d heat problems
function assemble!{E}(assembly::Assembly, problem::Problem{Heat}, element::Element{E}, time, ::Type{Val{Symbol("2D")}})
info("Unknown element type $E for 2d heat problem!")
end
typealias Heat2DVolumeElements Union{Tri3, Tri6, Quad4}
typealias Heat2DSurfaceElements Union{Seg2, Seg3}
function assemble!{E<:Heat2DVolumeElements}(assembly::Assembly, problem::Problem{Heat}, element::Element{E}, time, ::Type{Val{Symbol("2D")}})
gdofs = get_gdofs(problem, element)
2016-06-19 20:01:37 +03:00
field_name = get_unknown_field_name(problem)
nnodes = length(element)
K = zeros(nnodes, nnodes)
fq = zeros(nnodes)
2015-11-27 10:10:00 +02:00
for ip in get_integration_points(element)
detJ = element(ip, time, Val{:detJ})
w = ip.weight*detJ
2015-11-27 10:10:00 +02:00
N = element(ip, time)
2016-06-19 20:01:37 +03:00
if haskey(element, "$field_name thermal conductivity")
dN = element(ip, time, Val{:Grad})
2016-06-19 20:01:37 +03:00
k = element("$field_name thermal conductivity", ip, time)
K += w*k*dN'*dN
2015-10-28 04:29:14 +02:00
end
2016-06-19 20:01:37 +03:00
if haskey(element, "$field_name load")
f = element("$field_name load", ip, time)
fq += w*N'*f
2015-10-28 04:29:14 +02:00
end
2016-07-01 02:55:56 +03:00
end
T = vec(element[field_name](time))
fq -= K*T
add!(assembly.K, gdofs, gdofs, K)
add!(assembly.f, gdofs, fq)
end
function assemble!{E<:Heat2DSurfaceElements}(assembly::Assembly, problem::Problem{Heat}, element::Element{E}, time, ::Type{Val{Symbol("2D")}})
gdofs = get_gdofs(problem, element)
field_name = get_unknown_field_name(problem)
nnodes = length(element)
K = zeros(nnodes, nnodes)
fq = zeros(nnodes)
for ip in get_integration_points(element)
detJ = element(ip, time, Val{:detJ})
w = ip.weight*detJ
N = element(ip, time)
2016-06-19 20:01:37 +03:00
if haskey(element, "$field_name flux")
g = element("$field_name flux", ip, time)
fq += w*N'*g
2015-10-28 04:29:14 +02:00
end
end
2016-06-19 20:01:37 +03:00
T = vec(element[field_name](time))
fq -= K*T
add!(assembly.K, gdofs, gdofs, K)
add!(assembly.f, gdofs, fq)
2015-10-28 04:29:14 +02:00
end