Hello! I’ve been trying to solve a PDE for a 2x2 Q tensor, symmetric and with Trace(Q) = 0, and the approach that I’ve been following is by first define a vector space and from it built the tensor entity. Here I put the tensor that I want to build:
So far I’ve been OK, but I get the following error when I use the solve
function:
AttributeError: 'ListTensor' object has no attribute 'vector'
I’m not sure if my approach is correct and if so, how to pass correctly to the solve
function.
Here’s my code:
## Define vector elements and function spaces
## Define function spaces
Q = VectorFunctionSpace(mesh, 'P', 2)
U = VectorFunctionSpace(mesh, 'P', 2)
q = TrialFunction(Q)
r = TestFunction(Q)
q_ten = as_tensor(((cos(q[0]), sin(q[1])),
(sin(q[1]), -cos(q[0]))))
r_ten = as_tensor(((r[0], 0),
(0, r[1])))
## Define boundaries
inflow = 'near(x[0], 0)'
outflow = 'near(x[0], 0.5)'
walls = 'near(x[1], 0) || near(x[1], 0.2)'
## Define inflow profile for the velocity
inflow_profile = ('10.0*1.5*(0.1 - x[1])*x[1]*pow(0.1, 2)', '0')
## Define boundary conditions for the velocity
bcu_inflow = DirichletBC(U,
Expression(inflow_profile,
degree=2),
inflow)
bcu_walls = DirichletBC(U,
Constant((0, 0)),
walls)
bcu = [bcu_inflow, bcu_walls] ## Colect all boundary conditions for the velocity
## Define boundary conditions for the order parameter
## Define initial value for the order parameter
io = '0.8'
initial_order = Expression((io, io), degree=2)
bcq_inflow = DirichletBC(Q,
initial_order,
outflow)
bcq_walls = DirichletBC(Q,
initial_order,
walls)
bcq = [bcq_inflow, bcq_walls] ## Colect all boundary conditions for the order parameter
## Define trial and test functions
q_int = TrialFunction(Q)
u = TrialFunction(U)
r_int = TestFunction(Q)
v = TestFunction(U)
## Declare trial and test functions as tensors
q = as_tensor(((q_int[0], q_int[1]),
(q_int[1], -q_int[0])))
r = as_tensor(((r_int[0], r_int[1]),
(r_int[1], -r_int[0])))
# Define functions for solutions at previous and current time steps
q_n_int = Function(Q)
u_n = Function(U)
q_int = Function(Q)
u_ = Function(U)
## Declare previous functions as tensors
q_n = as_tensor(((q_n_int[0], q_n_int[1]),
(q_n_int[1], -q_n_int[0])))
q_ = as_tensor(((q_int[0], q_int[1]),
(q_int[1], -q_int[0])))
## Define epsilon tensor
def epsilon(u):
return sym(nabla_grad(u))
## Define vorticity tensor
def omega(u):
return skew(nabla_grad(u))
## Define L tensor
def L(u):
L1 = (1/3.) * dot((lamb*epsilon(u) + omega(u)), Identity(len(u)))
L2 = (1/3.) * dot((lamb*epsilon(u) - omega(u)), Identity(len(u)))
return L1 + L2
## Define N tensor
def N(q, u):
N1 = dot(lamb*epsilon(u) + omega(u), q)
N2 = dot(q, lamb*epsilon(u) - omega(u))
N3 = -2*lamb*(q + Identity(mesh.geometry().dim())/3.) * inner(q, nabla_grad(u))
return N1 + N2 + N3
## Define expressions used in variational forms
k1 = Constant(dt)
k2 = Constant(Pe)
## Define variational problem for step 1
F1 = inner((q - q_n) / k1, r)*dx \
+ inner(dot(u_n, nabla_grad(q_n)),r)*dx \
- (1/k2) * inner(nabla_grad(q), nabla_grad(r))*dx \
- inner(L(u_n), r)*dx \
- inner(N(q_n, u_n), r)*dx
a1 = lhs(F1)
L1 = rhs(F1)
# Assemble matrices
A1 = assemble(a1)
# Apply boundary conditions to matrices
[bc.apply(A1) for bc in bcq]
# Time-stepping
t = 0
for n in range(num_steps):
# Update current time
t += dt
# Step 1: Tentative velocity step
b1 = assemble(L1)
[bc.apply(b1) for bc in bcq]
solve(A1, q_.vector(), b1, 'bicgstab', 'hypre_amg')
Hope you can help me.
Thanks!