Hi Everbody,
I am facing a small issue while simulating a simple heat transfer conduction problem of a bar with a Dirichlet condition at one end an d a Neumann at the other end .
As long I do not include the density and capacity close to the time derivative everything is Ok ( only with a term \frac{\partial T}{\partial t} instead of \rho c_{p} \frac{\partial T}{\partial t}), but when I introduce it I get
- some oscillations close to the Dirichlet boundary condition ( even though this can be cured with quadratic elements )
- a temperature field that does not evolve in time
see attached pictures
Here is the code I used
# density (kg.m^-3)
rho = 8200.0
# capacity (J/Kg.K)
cp = 435.0
RhoCp = Constant(rho*cp)
# conductivity (W/m.K)
k = 11.5
# Boundary/Initial condtions --------------------------------------------------
# build plate temperature (K)
Tplate = 353.0
T_plate = Constant(Tplate)
# initial temperature (K)
T0 = Constant(293.0)
# imposed flux
Q = 100.0
# New version with better time stepping
T = 1.0 # final time
num_steps = 50 # number of time steps
dt = T / num_steps # time step size
l = 20.0
b = 4.0
h = 2.0
mesh = BoxMesh(Point(0, 0, 0), Point(l, b, h), 40, 8, 4)
tol=1E-8
class BoundaryBottom(SubDomain):
def inside(self, x, on_boundary):
return x[0] < tol
class BoundaryTop(SubDomain):
def inside(self, x, on_boundary):
return x[0] > l - tol
def Bottom(x, on_boundary):
return near(x[0], 0.)
def Top(x, on_boundary):
return near(x[0], l)
# Define subdomains for boundary conditions
sub_domains = MeshFunction("size_t", mesh, mesh.topology().dim())
sub_domains.set_all(0)
boundaryBottom = BoundaryBottom()
boundaryTop = BoundaryTop()
boundaryBottom.mark(sub_domains, 1)
boundaryTop.mark(sub_domains, 2)
facets = MeshFunction("size_t", mesh, 2)
AutoSubDomain(Bottom).mark(facets, 1)
AutoSubDomain(Top).mark(facets, 2)
ds = Measure("ds", subdomain_data=facets)
# Define variational problem
V = FunctionSpace(mesh, 'P', 1)
u = TrialFunction(V)
v = TestFunction(V)
f = Constant(0)
# define initial temperature
# 1) Constant one does the job
Tinit = interpolate(T0, V)
Tinit.rename("Temperature previous", "temperature profile at previous time step")
#Tplate = interpolate(T_plate, V)
BC = []
BC1 = DirichletBC(V, T_plate, boundaryBottom)
BC.append(BC1)
Neumann = Q*v*ds(2)
# Simplified one
# 1) Without rho*cp
F = u*v*dx + dt*dot(k*grad(u), grad(v))*dx - (Tinit + dt*f)*v*dx -dt*Neumann
a, L = lhs(F), rhs(F)
# 2) With rho*cp
F = RhoCp*u*v*dx + dt*dot(k*grad(u), grad(v))*dx - (RhoCp*Tinit + dt*f)*v*dx -dt*Neumann
a, L = lhs(F), rhs(F)
vtkfile = File('VTK/Temperature.pvd')
u = Function(V, name='Temperature')
t = 0
for n in range(num_steps):
print("current time is " + str(t) + " s")
print("Completion is " + str(100*(t/T))+ " %")
t += dt
# Compute solution
solve(a == L, u, BC)
# Save to file and
vtkfile << (u, t)
# Update previous solution
Tinit.assign(u)
# Update current time
I used the variational formulation described in
which seems correct to me .
I also got inspired from
but interestingly these constant are not accounted there
Any help/advice trick/would be very appreciated.
thanks,
Quentin