Hello, I’m trying to solve an equation with a rank 2 tensor order parameter \sigma_{ij}, but I’ve been having some problems using tensors with Fenics. However, because it’s only rank 2 and it’s symmetric and traceless I can reformulate everything in terms of two scalar functions \sigma_{xx} and \sigma_{yy}.
However if some other equation for a vector has a coupling of the form \partial_j\sigma_{ij} = \partial_x\sigma_{ix} + \partial_y\sigma_{iy} I should now write this coupling as derivative with respect to x of one of the scalar functions and derivative with respect to y of the other. How can I do this on Fenics?
So there is a Vector function space and one of the terms is the divergence above, so I need to build a vector whose x component is \partial_x\sigma_{xx} + \partial_y\sigma_{xy} and whose y component is \partial_x\sigma_{xy} - \partial_y\sigma_{xx}, and the sigmas are part of a mixed space defined as:
P = FiniteElement('P', mesh.ufl_cell(), 1)
MFS = FunctionSpace(mesh, MixedElement([P,P]), constrained_domain = PeriodicBoundary())
Q_ = Function(MFS)
qxx_, qxy_ = split(Q_)
How can I build such a vector from these functions?
Thanks
You can write the partial derivative of some expression f
with respect to the i
-th spatial coordinate as f.dx(i)
in UFL. So, for example, the partial derivative with respect to x of qxx_
in your example would be qxx_.dx(0)
and the partial derivative with respect to y would be qxx_.dx(1)
. (Note that this use of “dx
” for partial derivatives is not related to the integration measure dx
.)
4 Likes
Thank you for your reply. And how would you go about building a vector out of those quantities. If for instance my force should be a 2d vector f = (\partial_y q_{xy},\partial_x q_{xx}), this would translate to my equation in weak form as
... = ... + \int f\cdot v d^d r
where v is a test function
I’ve tried defining f as a function on the same space as the quantity I want to solve for
f = Function(W)
# Assign f
res = ... + dot(f,v)*dx
solve(res==0,...)
where W
is a Vector function space. I’ve tried to assign f
in a few trivial ways like f[0] = qxy_.dx(1)
and things like that that seem to be completely wrong. How would I go about building a vector out of scalar quantities?
Thanks again.
You can use the as_vector
function, e.g.,
f = as_vector([qxy_.dx(1),qxx_.dx(0)])
Note that there is also an as_matrix
function, which works analogously, and a more general as_tensor
function, where you can use index notation to define arbitrary-rank tensors.
1 Like
Thanks! This is all I needed