This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

how to concatenate two scalar functions into a vector function

0 votes

I am solving a complex PDE and have split the real and imaginary parts into two separate PDEs and solved. I now have two scalar functions, that I would like to combine back into a vector function so that I can plot the results.

I found the question

https://fenicsproject.org/qa/8838/combine-scalar-valued-functions-into-vector-valued-function

but I don't want to use the function in a form so it doesn't appear to apply, plus I am using the c++ api and I can't find an equivalent to the as_vector function.

I want to do something like this:

auto V = std::make_shared<real::FunctionSpace>(mesh);
auto W = std::make_shared<imaginary::FunctionSpace>(mesh);

auto u0 = std::make_shared<RealBoundaryCondition>(*mesh);
auto w0 = std::make_shared<ImaginaryBoundaryCondition>(*mesh);

auto f = std::make_shared<dolfin::Constant>(0);

auto boundary = std::make_shared<DirichletBoundary>();
dolfin::DirichletBC realbc(V, u0, boundary);
dolfin::DirichletBC imaginarybc(W, w0, boundary);

real::BilinearForm a(V, V);
real::LinearForm L(V);
L.f = f;

imaginary::BilinearForm b(W, W);
imaginary::LinearForm M(W);
M.f = f;

dolfin::Function u(V);
dolfin::solve(a == L, u, realbc);

dolfin::Function w(W);
dolfin::solve(b == M, w, imaginarybc);

[combine u and w into a single vector function "vec"]

dolfin::plot(vec);
dolfin::interactive();
asked Nov 24, 2016 by rviertel FEniCS Novice (700 points)

What about getting the vector() for the two scalar functions and the vector function and then simply copy the values over?

Could you provide an example on how to do this and then plot the result? I'm new to Fenics

Can't really help with c++ (well, I could, but don't have time right now), the following seems to work in python though and you should be able to translate it over to c++ pretty quick (note I save to an XDMF to view with paraview)

from dolfin import *
mesh = UnitSquareMesh(32,32)
V = FunctionSpace(mesh,'CG',1)
u=Function(V)
u.interpolate(Expression("x[0]",degree=1))
v=Function(V)
v.interpolate(Expression("1.0+x[1]",degree=1))
W = VectorFunctionSpace(mesh,'CG',1,dim=2)
w = Function(W)
ua=u.vector().array()
va=v.vector().array()
wa=w.vector().array()
wa[::2]=ua
wa[1::2]=va
w.vector().set_local(wa)
file = XDMFFile("w.xdmf")
file.write(w,0.0)

That did it. Thank you!

if you repost your comment as an answer, i'll accept it so you get credit

Okay, will do. Might be worth waiting to see if one of the dev's has a better/cleaner solution though.

1 Answer

+1 vote
 
Best answer

You could try getting the vector for the scalar and vector functions and then copying the data. The following seems to work in python and should be relatively straightforward to replicate with the C++ API

from dolfin import *
mesh = UnitSquareMesh(32,32)
V = FunctionSpace(mesh,'CG',1)
u=Function(V)
u.interpolate(Expression("x[0]",degree=1))
v=Function(V)
v.interpolate(Expression("1.0+x[1]",degree=1))
W = VectorFunctionSpace(mesh,'CG',1,dim=2)
w = Function(W)
ua=u.vector().array()
va=v.vector().array()
wa=w.vector().array()
wa[::2]=ua
wa[1::2]=va
w.vector().set_local(wa)
answered Nov 24, 2016 by Brendan FEniCS Novice (890 points)
selected Nov 24, 2016 by rviertel
...