"""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