Hi,
When I try to run the provided code I get the error "All terms in form must have same rank" which means that your weak formula is not well-posed. The generic weak formulation is a(u,v)=L(v) and it seems you forgot to multiply by the test function v, here's the fix:
a = (T*v + inner(nabla_grad(T), nabla_grad(v)))*dx() - del_t*(T-T0)*v*ds(0) - del_t*(T-T0)*v*ds(1)
L = T_1*v*dx() - del_t*source*v*ds(0)
If you have trouble defining the formula you can just add all the terms in a single functionnal then call rhs and lhs (right hand side/left hand side) to sort it:
Fa = (T*v + inner(nabla_grad(T), nabla_grad(v)))*dx() - del_t*(T-T0)*ds(0) - del_t*(T-T0)*ds(1)
FL= T_1*v*dx() - del_t*source*ds(0)
F=Fa+FL
a=lhs(F)
L=rhs(F)
Which automatically builds the form. Then the code runs fine but you didn't define dt in the while loop so it stops.
If you define dt it will run. Be careful you marked both subdomains as 0:
bottom.mark(boundary_parts, 0)
top.mark(boundary_parts, 0)
in order to distinguish the top of the box, the bottom of the box and the interior you should do:
boundary_parts = FacetFunction("size_t", mesh)
boundary_parts.set_all(0) #marks whole cube as domain 0
class Bottom(SubDomain):
def inside(self, x, on_boundary):
tol = 1E-14
return on_boundary and abs(x[2]) < tol
bottom = Bottom()
bottom.mark(boundary_parts, 1) #marks bottom of the cube as 1
class Top(SubDomain):
def inside(self, x, on_boundary):
tol = 1E-14
return on_boundary and abs(x[2] - zmax) < tol
top = Top()
top.mark(boundary_parts, 2) #marks the top of the cube as 2
then you can define a measure on each of the subdomains:
dx=Measure('dx')[boundary_parts]
ds=Measure('ds')[boundary_parts]
With all this, you can get a running code, still, I'm not much into heat conduction and I don't know if the output is what you were looking for, anyway here's the full code, hoping this could help you:
from dolfin import *
import numpy as np
mesh = UnitCubeMesh(10,10,10)
xmax, ymax, zmax = 1, 1, 1
V = FunctionSpace(mesh, 'Lagrange', 1)
boundary_parts = FacetFunction("size_t", mesh)
boundary_parts.set_all(0) #marks whole cube as domain 0
class Bottom(SubDomain):
def inside(self, x, on_boundary):
tol = 1E-14
return on_boundary and abs(x[2]) < tol
bottom = Bottom()
bottom.mark(boundary_parts, 1) #marks bottom of the cube as 1
class Top(SubDomain):
def inside(self, x, on_boundary):
tol = 1E-14
return on_boundary and abs(x[2] - zmax) < tol
top = Top()
top.mark(boundary_parts, 2) #marks the top of the cube as 2
dx=Measure('dx')[boundary_parts]
ds=Measure('ds')[boundary_parts]
plot(boundary_parts)
T = TrialFunction(V)
v = TestFunction(V)
T0 = Constant("293")
T_1= interpolate(T0, V)
del_t=1
t_ges=10
source=Constant("5")
Fa = (T*v + inner(nabla_grad(T), nabla_grad(v)))*dx() - del_t*(T-T0)*v*ds(1) - del_t*(T-T0)*v*ds(2)
FL= T_1*v*dx() - del_t*source*v*ds(1)
F=Fa+FL
a=lhs(F)
L=rhs(F)
A = assemble(a, exterior_facet_domains = boundary_parts)
b = None
T = Function(V)
t = del_t
dt = 0.5
while t <= t_ges:
b = assemble(L, tensor=b, exterior_facet_domains=boundary_parts)
solve(A, T.vector(), b, 'lu')
t += dt
T_1.assign(T)
plot(T_1)