Split a 3D vector function into a scalar and a 2D vector

Hello, I want to split a 3D vector function into a scalar and a 2D vector, but the typical split() function splits it into 3 scalars instead, anyone know how to do that split?

from  dolfin  import *
mesh = RectangleMesh(dl.Point(0., 0.), dl.Point(5., 5.),10,10)
V = VectorFunctionSpace(mesh, 'Lagrange', 2, 3)
X = Function(V)

I want to split the first dimension of X into T for temperature, and the second and third dimensions of X into u as 2D vector displacement.

Thank you in advance!

I would suggest you use a MixedElement, i.e.

from dolfin import * 
mesh = RectangleMesh(Point(0., 0.), Point(5., 5.), 10, 10)
v_el = VectorElement("CG", mesh.ufl_cell(), 1, dim=2)
t_el = FiniteElement("CG", mesh.ufl_cell(), 1) 
V = FunctionSpace(mesh, MixedElement([v_el, t_el]))
uT = Function(V)
u = uT.sub(0)
T = uT.sub(1)

Good idea! A following up question is that I ran into this error saying that there is no sub

T = u.sub(1)
AttributeError: ‘Argument’ object has no attribute ‘sub’

Looks like the following codes worked instead of sub(), what do you think?

u,T = split(uT)

So I guess you are using u=TrialFunction(V). Then you need to use split.

Yes, thanks! Following on the same setup, how should I correctly define surface integrant ds() for only one of the functions?

for example, I want to define ds(1) for the top edge for T and ds(2) for the right edge for u, I usually use the following code:

class TopSurf(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and near(x[1],1.)
class RightSurf(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and near(x[0],1.)
boundary_parts = MeshFunction("size_t", mesh, mesh.topology().dim()-1, 0)
boundary_parts.set_all(0) #marks whole cube as domain 0

top = TopSurf()
top.mark(boundary_parts, 1)
right = RightSurf()
right.mark(boundary_parts, 2)


But looks like using the above code, ds(1) ended up to be the top boundary of both T and u, and same situation for ds(2). I tried to use something like ds(1).sub(1) but didn’t work.

Integration measures are not directly linked to the function space. Simply integrate only the subfunction over that boundary, and not both functions.