from fenics import *
import numpy as np
-------------------------
Parameters
-------------------------
rho = 1.0 # density
mu = 0.01 # viscosity
kappa = 0.01 # thermal diffusivity
beta = 0.01 # thermal expansion
g = Constant((0.0, -9.81)) # gravity
T_in = 290.0
T_hot = 310.0
dt = 0.01
t_end = 0.5
-------------------------
Mesh
-------------------------
nx, ny = 40, 40
mesh = UnitSquareMesh(nx, ny)
-------------------------
Function spaces
-------------------------
V = VectorElement(“P”, mesh.ufl_cell(), 2) # velocity
Q = FiniteElement(“P”, mesh.ufl_cell(), 1) # pressure
S = FiniteElement(“P”, mesh.ufl_cell(), 1) # temperature
W = FunctionSpace(mesh, MixedElement([V, Q, S]))
w = Function(W) # current solution
w_n = Function(W) # previous solution
(u, p, T) = split(w)
(u_n, p_n, T_n) = split(w_n)
(v, q, s) = TestFunctions(W)
-------------------------
Boundary conditions
-------------------------
inlet = “near(x[0], 0.0)”
outlet = “near(x[0], 1.0)”
walls = “near(x[1], 0.0) || near(x[1], 1.0)”
bcu_inlet = DirichletBC(W.sub(0), Constant((1.0, 0.0)), inlet)
bcu_walls = DirichletBC(W.sub(0), Constant((0.0, 0.0)), walls)
bcp_outlet = DirichletBC(W.sub(1), Constant(0.0), outlet)
bcT_inlet = DirichletBC(W.sub(2), Constant(T_in), inlet)
bcT_hotwall = DirichletBC(W.sub(2), Constant(T_hot), “near(x[1], 0.0)”)
bcs = [bcu_inlet, bcu_walls, bcp_outlet, bcT_inlet, bcT_hotwall]
-------------------------
Weak forms
-------------------------
Time discretization
u_mid = 0.5*(u + u_n)
T_mid = 0.5*(T + T_n)
Momentum
F_m = rhodot((u - u_n)/dt, v)dx
+ rhodot(dot(u_mid, nabla_grad(u_mid)), v)dx
+ 2muinner(sym(grad(u_mid)), sym(grad(v)))dx
- div(v)pdx
- qdiv(u)dx
- rhobeta*(T_mid - T_in)*dot(g, v)*dx
Energy
F_T = (T - T_n)/dtsdx
+ dot(u_mid, grad(T_mid))sdx
+ kappa*dot(grad(T_mid), grad(s))*dx
F = F_m + F_T
-------------------------
Stabilization (SUPG/PSPG)
-------------------------
h = CellDiameter(mesh)
u_mag = sqrt(dot(u_mid, u_mid) + 1e-10)
tau_m = h/(2.0u_mag) # momentum stabilization
tau_c = hh/(2.0*kappa) # thermal stabilization
r_m = rho*((u - u_n)/dt + dot(u_mid, nabla_grad(u_mid)))
- div(2musym(grad(u_mid))) + grad(p)
- rhobeta(T_mid - T_in)g
r_T = (T - T_n)/dt + dot(u_mid, grad(T_mid)) - kappadiv(grad(T_mid))
F += tau_m*dot(r_m, dot(u_mid, grad(v)))*dx \
- tau_cr_Tdot(u_mid, grad(s))*dx
-------------------------
Solve nonlinear system
-------------------------
J = derivative(F, w)
problem = NonlinearVariationalProblem(F, w, bcs, J)
solver = NonlinearVariationalSolver(problem)
prm = solver.parameters
prm[“nonlinear_solver”] = “newton”
prm[“newton_solver”][“absolute_tolerance”] = 1e-8
prm[“newton_solver”][“relative_tolerance”] = 1e-7
prm[“newton_solver”][“maximum_iterations”] = 25
prm[“newton_solver”][“linear_solver”] = “mumps”
-------------------------
Time stepping
-------------------------
t = 0.0
vtkfile_u = File(“velocity.pvd”)
vtkfile_T = File(“temperature.pvd”)
while t < t_end:
t += dt
print(f"Time = {t:.3f}")
solver.solve()
(u_sol, p_sol, T_sol) = w.split()
vtkfile_u << (u_sol, t)
vtkfile_T << (T_sol, t)
w_n.assign(w)
My solver keeps getting diverging