Keeping the derivative in one direction

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?


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.)


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


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