-
Notifications
You must be signed in to change notification settings - Fork 268
/
Copy pathheatconv.py
94 lines (75 loc) · 2.56 KB
/
heatconv.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""Heat equation in moving media."""
# Credits: Jan Blechta
# https://github.com/blechta/fenics-handson/blob/master/heatconv
from dolfin import *
set_log_level(30)
# Create mesh and build function space
mesh = UnitSquareMesh(30, 30, "crossed")
V = FunctionSpace(mesh, "Lagrange", 1)
# Create boundary markers
tdim = mesh.topology().dim()
boundary_parts = MeshFunction("size_t", mesh, tdim - 1)
left = AutoSubDomain(lambda x: near(x[0], 0.0))
right = AutoSubDomain(lambda x: near(x[0], 1.0))
bottom = AutoSubDomain(lambda x: near(x[1], 0.0))
left.mark(boundary_parts, 1)
right.mark(boundary_parts, 2)
bottom.mark(boundary_parts, 2)
# Initial condition and right-hand side
ic = Expression("""pow(x[0] - 0.25, 2) + pow(x[1] - 0.25, 2) < 0.2*0.2
? -25.0 * ((pow(x[0] - 0.25, 2) + pow(x[1] - 0.25, 2)) - 0.2*0.2)
: 0.0""", degree=1,
)
f = Expression("""pow(x[0] - 0.75, 2) + pow(x[1] - 0.75, 2) < 0.2*0.2
? 1.0
: 0.0""", degree=1,
)
# Equation coefficients
K = Constant(1e-2) # thermal conductivity
g = Constant(0.01) # Neumann heat flux
b = Expression(("-(x[1] - 0.5)", "x[0] - 0.5"), degree=1) # convecting velocity
# Define boundary measure on Neumann part of boundary
dsN = Measure("ds", subdomain_id=1, subdomain_data=boundary_parts)
# Define steady part of the equation
def operator(u, v):
return (K * inner(grad(u), grad(v)) - f * v + dot(b, grad(u)) * v
) * dx - K * g * v * dsN
# Define trial and test function and solution at previous time-step
u = TrialFunction(V)
v = TestFunction(V)
u0 = Function(V)
# Time-stepping parameters
dt = 0.02
theta = Constant(0.5) # Crank-Nicolson scheme
# Define time discretized equation
F = ((1.0 / dt) * inner(u - u0, v) * dx
+ theta * operator(u, v)
+ (1.0 - theta) * operator(u0, v)
)
# Define boundary condition
bc = DirichletBC(V, Constant(0.0), boundary_parts, 2)
# Prepare solution function and solver
u = Function(V)
problem = LinearVariationalProblem(lhs(F), rhs(F), u, bc)
solver = LinearVariationalSolver(problem)
# Prepare initial condition
u0.interpolate(ic)
u.interpolate(ic)
######################################################Time-stepping
from vedo.dolfin import plot
t = 0.0
while t < 3:
solver.solve()
plot(u,
text=__doc__+"\nTemperature at t = %g" % t,
style=2,
axes=3,
lw=0, # no mesh edge lines
warp_zfactor=0.1,
isolines={"n": 12, "lw":1, "c":'black', "alpha":0.1},
scalarbar=False,
interactive=False,
).clear()
# Move to next time step
u0.assign(u)
t += dt