mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-22 02:40:51 +00:00
better heat example
This commit is contained in:
@@ -312,14 +312,22 @@ function call(solver::Solver)
|
||||
info("Starting nonlinear iteration #$(solver.iteration)")
|
||||
|
||||
# 2.1 update linearized assemblies (if needed)
|
||||
info("Assembling problems ...")
|
||||
tic()
|
||||
for problem in solver.problems
|
||||
problem.assembly.changed = true # force reassembly
|
||||
assemble!(problem, solver.time)
|
||||
end
|
||||
t1 = round(toq(), 2)
|
||||
info("Assembled in $t1 seconds.")
|
||||
|
||||
# 2.2 call solver for linearized system (default: direct lu factorization)
|
||||
info("Solve linear system ...")
|
||||
tic()
|
||||
u, la = solve_linear_system(solver, Val{solver.linear_system_solver})
|
||||
push!(solver.norms, (norm(u), norm(la)))
|
||||
t1 = round(toq(), 2)
|
||||
info("Solved Ax = b in $t1 seconds.")
|
||||
|
||||
# 2.3 update solution back to elements
|
||||
for problem in solver.problems
|
||||
|
||||
+41
-24
@@ -13,48 +13,65 @@ using JuliaFEM.Test
|
||||
3 => [1.0,1.0],
|
||||
4 => [0.0,1.0])
|
||||
|
||||
# volume element
|
||||
element = Element(Quad4, [1, 2, 3, 4])
|
||||
# define volume element
|
||||
el1 = Element(Quad4, [1, 2, 3, 4])
|
||||
|
||||
update!(element, "geometry", X)
|
||||
update!(element, "temperature thermal conductivity", 6.0)
|
||||
update!(element, "temperature load", [12.0, 12.0, 12.0, 12.0])
|
||||
update!(element, "density", 36.0)
|
||||
update!(el1, "geometry", X)
|
||||
update!(el1, "temperature thermal conductivity", 6.0)
|
||||
update!(el1, "temperature load", 12.0)
|
||||
update!(el1, "density", 36.0)
|
||||
|
||||
# boundary element
|
||||
boundary_element = Element(Seg2, [1, 2])
|
||||
update!(boundary_element, "geometry", X)
|
||||
# linear ramp from 0 to 6 in time 0 to 1
|
||||
update!(boundary_element, "temperature flux", 0.0 => 0.0, 1.0 => 6.0)
|
||||
# define boundary element for flux
|
||||
el2 = Element(Seg2, [1, 2])
|
||||
update!(el2, "geometry", X)
|
||||
# linear ramp from 0 -> 6 in time 0 -> 1
|
||||
update!(el2, "temperature flux", 0.0 => 0.0, 1.0 => 6.0)
|
||||
|
||||
# define heat problem and push elements to problem
|
||||
problem = Problem(Heat, "one element heat problem", 1)
|
||||
push!(problem, element, boundary_element)
|
||||
push!(problem, el1, el2)
|
||||
|
||||
# Set constant source f=12 with k=6. Accurate solution is
|
||||
# T=1 on free boundary, u(x,y) = -1/6*(1/2*f*x^2 - f*x)
|
||||
# define boundary element for dirichlet boundary condition
|
||||
el3 = Element(Seg2, [3, 4])
|
||||
update!(el3, "geometry", X)
|
||||
update!(el3, "temperature 1", 0.0)
|
||||
|
||||
boundary_condition = Problem(Dirichlet, "T=0 on top", 1, "temperature")
|
||||
push!(boundary_condition, el3)
|
||||
|
||||
# manual assembling of problem + solution:
|
||||
assemble!(problem, 0.0)
|
||||
A = full(problem.assembly.K)
|
||||
b = full(problem.assembly.f)
|
||||
|
||||
A_expected = [
|
||||
4.0 -1.0 -2.0 -1.0
|
||||
-1.0 4.0 -1.0 -2.0
|
||||
-2.0 -1.0 4.0 -1.0
|
||||
-1.0 -2.0 -1.0 4.0]
|
||||
|
||||
@test isapprox(A, A_expected)
|
||||
|
||||
free_dofs = [1, 2]
|
||||
@test isapprox(A, A_expected)
|
||||
@test isapprox(A[free_dofs, free_dofs] \ b[free_dofs], [1.0, 1.0])
|
||||
|
||||
# using Solver
|
||||
solver = Solver("solve heat problem")
|
||||
solver.is_linear_system = true
|
||||
push!(solver, problem, boundary_condition)
|
||||
|
||||
# Set constant source f=12 with k=6. Accurate solution is
|
||||
# T=1 on free boundary, u(x,y) = -1/6*(1/2*f*x^2 - f*x)
|
||||
# when boundary flux not active (at t=0)
|
||||
solver.time = 0.0
|
||||
call(solver)
|
||||
# interpolate temperature at middle of element 2 (flux boundary) at time t=0:
|
||||
T = el2("temperature", [0.0], 0.0)
|
||||
@test isapprox(T[1], 1.0)
|
||||
|
||||
# Set constant flux g=6 on boundary. Accurate solution is
|
||||
# u(x,y) = x which equals T=1 on boundary.
|
||||
# at time t=1.0 all loads should be on.
|
||||
empty!(problem.assembly)
|
||||
assemble!(problem, 1.0)
|
||||
A = full(problem.assembly.K)
|
||||
b = full(problem.assembly.f)
|
||||
T = A[free_dofs, free_dofs] \ b[free_dofs]
|
||||
@test isapprox(T, [2.0, 2.0])
|
||||
solver.time = 1.0
|
||||
call(solver)
|
||||
T = el2("temperature", [0.0], 1.0)
|
||||
@test isapprox(T[1], 2.0)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user